【C/C++】关于C++的名字查找与继承

为了将问题简化,首先来看一段代码:

#include <tchar.h>
#include "stdio.h"

class A
{
public:
    void func()
    {
        printf("A::func\n");
    }
};

class B : public A
{
public:
    void func(int n)    // 注意这里func与A的func同名,但参数不同
    {
        printf("B::func\n");
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    B b;
    b.func();    // 期望调用B的基类A的func()函数
    return 0;
}

这里本来是期望调用A::func()函数,但很抱歉,编译器不会如您所愿,编译器会报错:

1>f:\testproj\consoletest_vs2005\test\test.cpp(25) : error C2660: 'B::func' : function does not take 0 arguments

这是什么原因呢?翻阅C++ Primer可以得到答案:

C++ Primer 中文第四版P500的注解:如果派生类重定义了重载成员,则通过派生类型只能访问派生类中重定义的那些成员。

为什么会这样?要理解这个问题就需要知道了解C++中名字查找与继承(C++ Primer 中文第四版P501的关键概念):

确定函数调用遵循以下四个步骤:

1.首先确定进行函数调用的对象、引用或指针的静态类型。

2.在该类中查找函数,如果找不到,就在直接基类中查找,如此循着类的继承往上找,直到找到该函数或者查找完最后一个类。如果不能在类或其相关基类中找到该名字,则调用是错误的。

3.一旦找到了该名字,就进行常规类型检查(7.1.2节),查看如果给定找到的定义,该函数是否合法。

4.假定函数合法,编译器就生成代码。如果函数是虚函数且通过引用或指针调用,则编译器生成代码以确定根据对象的动态类型运行哪个函数版本,否则,编译器生成代码直接调用函数。

以上就是这个问题的解释。

原文地址:https://www.cnblogs.com/jeJee/p/2695000.html