为什么要调用来自直接父级的函数而不是祖父级类.这被称为函数覆盖吗?

san*_*eep 1 c++

class A
{
public:
void test ()
{
cout<<"In A";
}
};
class B :public A
{
public:
void test ()
{
cout<<"In B";
}
};
class C : public B
{

public:
int c;
};
int main()
{
C c;
c.test();
}

The result is: In B...
Run Code Online (Sandbox Code Playgroud)

Dav*_*eas 5

不,它不是重写,而是隐藏原始方法.

C++中的多态行为仅限于声明的方法virtual,并且类层次结构中该方法的每个实现都称为方法的覆盖.

struct base {
   virtual void foo();
   void bar();
};
struct derived : base {
   virtual void foo();
   void bar();
};
Run Code Online (Sandbox Code Playgroud)

在示例中base::foo并且derived::foo是覆盖.当您derived通过指针或类型引用使用类类型时base,将调用最终重写方法(层次结构中最低的方法:在本例中derived::foo).这里重要的一点是调用是通过指针或对base的引用:

void test() {
   derived d;
   base &b = d;
   b.foo(); // derived::foo() <- final overrider
   b.bar(); // base::bar()    <- non-virtual, no override
   d.bar(); // derived::bar() <- hides the method in base
}
Run Code Online (Sandbox Code Playgroud)

bar(或在您的情况下)情况下发生的情况是,当编译器找到调用时,d.bar()它需要确定要调用的方法.要找到方法,它将首先查看derived声明内部并找到derived::bar()(与之无关base::bar()),并且它将使用该方法而不在类层次结构中检查更高的值.如果需要在层次结构中调用更高的方法,可以通过获取更高类型的引用或完全限定要调用的方法来执行此操作.

请注意,隐藏不仅发生在签名完全匹配时,而且在编译器找到具有相同名称的方法的所有情况下:

struct base {
   void bar();
};
struct derived : base {
   void bar( int );
};
void test() {
   derived d;
   base & b;

   b.bar();    // ok: base::bar()
   d.bar(1);   // ok: derived::bar(int)
   //b.bar(1); // error: base has no bar method that takes an integer
   //d.bar();  // error: derived::bar takes an integer, base::bar is hidden
   d.base::bar(); // ok: fully qualifying tells the compiler where to look
}
Run Code Online (Sandbox Code Playgroud)