2012-02-28 87 views
13
class Base 
{ 
    public: 
    virtual void func() const 
    { 
    cout<<"This is constant base "<<endl; 
    } 
}; 

class Derived : public Base 
{ 
    public: 
    virtual void func() 
    { 
    cout<<"This is non constant derived "<<endl; 
    } 
}; 


int main() 
{ 
    Base *d = new Derived(); 
    d->func(); 
    delete d; 

    return 0; 
} 

为什么输出打印出“这是恒定基数”。然而,如果我删除基础版本的func()中的const,它会打印出“This is non constant derived derived”虚拟功能常量vs虚拟功能非常量

d-> func()应该调用Derived版本,即使基础func ?

+0

可能的重复http://stackoverflow.com/questions/7504300,http://stackoverflow.com/questions/3827374和http://stackoverflow.com/questions/4152799。 – 2012-02-28 19:12:54

+0

[虚函数是在基类中的常量,而不是在派生的常量]的可能重复(http://stackoverflow.com/questions/7504300/virtual-function-that-is-const-in-the-base- class-and-not-const-in-the-derived) – 2012-02-28 19:58:16

回答

28
virtual void func() const //in Base 
virtual void func()  //in Derived 

const部分是函数签名,这意味着派生类定义了一个新函数,而不是重写基类功能的实际的一部分。这是因为他们的签名不匹配。

当您删除const一部分,那么他们的签名相匹配,然后编译器看到的基类功能funcfunc重写版本,因此派生类的功能是,如果运行时类型的称为派生类中定义对象是Derived类型。这种行为称为运行时多态。

+0

我很困惑这里。如果两者都被视为2个不同的函数,为什么d-> func()调用派生版本,因为这里没有适用的const。 – vamsi 2012-02-28 19:15:30

+1

对。事实上,一个类通常定义两个相同的函数,一个是“const”,另一个不是。 – 2012-02-28 19:16:36

+2

@vamsi,'Base'的定义只包含一个函数,所以这就是所谓的函数。 – 2012-02-28 19:17:49

3

不,因为virtual void func()不是virtual void func() const的覆盖。

4

virtual void func()实际上是与virtual void func() const不同的签名。因此,您并未覆盖原始的只读基本函数。您最终在Derived中创建了一个新的虚拟函数。

如果您尝试创建指向成员函数(PTMF)的指针,您也可以了解更多信息,但这是非常罕见的必要条件(可能对研究或实践有好处)。

C++ 11中的override关键字特别方便,可以帮助避免这些类型的错误。然后编译器会告诉你,你在派生的'func'定义不会覆盖任何东西。