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”
d-&gt; func()应该正确调用Derived版本,即使Base func()是const右边的吗?
答案 0 :(得分:32)
virtual void func() const //in Base
virtual void func() //in Derived
const
部分实际上是函数签名的一部分,这意味着派生类定义了 new 函数而不是覆盖基类功能。这是因为他们的签名不匹配。
当您删除const
部分,然后它们的签名匹配,然后编译器将func
的派生类定义视为基类函数{{的重写版本 1}},因此如果对象的运行时类型是func
类型,则调用派生类函数。此行为称为运行时多态。
答案 1 :(得分:4)
virtual void func()
实际上与virtual void func() const
的签名不同。因此,您没有覆盖原始的只读基本函数。您最终在Derived中创建了一个新的虚拟函数。
如果您尝试创建指向成员函数(PTMF)的指针,您还可以了解更多相关信息,但这是一种罕见的必要条件(但可能对学习或实践有益)。
C ++ 11中的override关键字特别方便,可以帮助避免这些错误。然后,编译器会告诉您,派生中的'func'定义不会覆盖任何内容。
答案 2 :(得分:3)
不,因为virtual void func()
不是virtual void func() const
的覆盖。