2015-09-11 88 views
0

以下代码基于C++模板:完全指南的第298页上的示例。我删除了与我的问题无关的部分。继承基类成员函数的虚拟说明符

class Virtual { 
    public: 
    virtual void foo() { 
    } 
}; 

class Base : private Virtual { 
    public: 
    void foo() { 
     std::cout << "Base::foo()" << '\n'; 
    } 
}; 

class Derived : public Base { 
    public: 
    void foo() { 
     std::cout << "Derived::foo()" << '\n'; 
    } 
}; 

int main() 
{ 
    Base *p = new Derived; 
    p->foo(); // calls Derived::foo() 
} 

我不明白通话p->foo()如何结束调用Derived::foo。更具体地说,p的静态类型是Base*Base::foo是非虚拟的。现在,Base私自继承'虚拟',它有自己的foo,看起来好像Base::foo以某种方式从Virtual::foo获得virtual说明符。这里究竟发生了什么?

+0

'Base :: foo' **是虚拟的。 –

+1

U创建了Derived的一个实例,这就是它调用Derived的方法的原因。检查OOP继承。 –

+0

@KerrekSB这个问题是基于一个错误的假设。这发生在人们身上。清除误解帮助了我很多。这是否应该受到惩罚? – AlwaysLearning

回答

5

foovirtual继承自基类Virtual

事实上,编写virtualDerived::foo将是多余的,许多开发人员将省略它。一旦您在基类中将该函数标记为virtual,您就不能撤销virtual

您可以通过编写p->Base::foo();强制呼叫Base::foo,但这是一个丑陋的设计。

+0

啊。我不知何故忘记了这一点。谢谢。 – AlwaysLearning

+0

关于“你不能撤销虚拟性”的两个简要说明:1)你可以用'final'来停止新的虚拟函数,以及2)如果改变函数的签名,它将掩盖原始的虚拟性,即使你也使用相同的签名。 –