忽略范围说明符的C ++虚函数

时间:2015-04-12 05:22:10

标签: c++ scope polymorphism virtual vtable

请参阅以下C ++代码:

#include <iostream>

class A {
public:
    virtual ~A() {}
    virtual void display() {
        std::cout << "Display A"  << std::endl;
    }
};

class B : public A {
    // ! NO 'display()' function in this class.
};

class C : public B {
public:
    void display() {
        std::cout << "Display C" << std::endl;
        B::display();
    }
};


int main(void) {
    A* ptr = new C();
    ptr->display();
    delete ptr;

    return 0;
}

这是该程序的输出:

Display C 
Display A

我希望这个程序有一个编译错误,因为没有定义B :: display()。

有人可以解释一下这段代码的行为吗?

非常感谢你的时间!

3 个答案:

答案 0 :(得分:1)

  

有人可以解释一下这段代码的行为吗?

B只是继承了display中的A函数。因为,它的虚拟B可以将行为覆盖为不同的行为(即,如果它需要不同的实现,它可以创建一个,否则它可以采取它继承的内容)。

答案 1 :(得分:1)

您错误地将虚函数误认为是抽象函数。函数虚拟的,只要它有一个vtable条目,可以被基类的子类覆盖。但是,不需要基类来覆盖该条目。

例如,B::display()的vtable条目为A::display(),这是您在示例中看到的内容。

为了完整起见,您在C ++中声明抽象函数,如下所示:virtual void display() =0;没有正文。必须为C ++重写此函数以允许您实例化类类型,否则您将收到编译错误。

答案 2 :(得分:1)

根据C ++标准(10派生类)

  
      
  1. ...除非在派生类中重新声明,否则基类的成员是   也被认为是派生类的成员。基类   成员据说是派生类继承的。的继承   成员可以在表达式中以与其他成员相同的方式引用   派生类的成员,除非他们的名字被隐藏或   暧昧 ...
  2.   

因此,你可以在类A中引用继承的成员函数display,与类B中的其他成员一样。