鉴于以下代码段,
class Base
{
public:
virtual void eval() const
{
std::cout<<"Base Const Eval\n";
}
};
class Derived:public Base
{
public:
void eval()
{
std::cout<<"Derived Non-Const Eval\n";
}
};
int main()
{
Derived d;
Base* pB=&d;
pB->eval(); //This will call the Base eval()
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么pB-> eval()会调用Base :: eval()?
谢谢
在你的Derived类中,eval的原型与虚拟函数的原型不匹配Base.所以它不会覆盖虚函数.
Base::eval() const;
Derived::eval(); //No const.
Run Code Online (Sandbox Code Playgroud)
如果添加const Derived::eval(),则应该获得虚拟行为.
你可以在脑海中翻译:
virtual void Base::eval() const;
void Derived::eval() ;
Run Code Online (Sandbox Code Playgroud)
至
void eval(const Base *this, size_t vtable_offset);
void eval(Derived *this);
Run Code Online (Sandbox Code Playgroud)
并通过检查看到第二个符号与第一个符号的匹配程度.
这是因为一个声明为const而另一个声明为const.一个功能被另一个隐藏.Derived中的函数将其隐藏在Base中,因为它们具有相同的名称,而它们不是同一个函数.
我的编译器在这里发出警告,你的吗?
$ 10.3/2-"如果一个虚拟成员函数vf在一个类Base和一个Derived类中声明,直接或间接从Base派生,一个成员函数vf具有相同的名称,参数类型列表(8.3.5), 声明了base :: vf的cv-qualification和refqualifier(或不存在相同的),然后Derived :: vf也是虚拟的(无论是否如此声明)并且它覆盖了111 Base :: vf."
111)具有相同名称但作为虚拟功能的不同参数列表(条款13)的功能不一定是虚拟的并且不会覆盖.在覆盖函数的声明中使用虚拟说明符是合法的但是冗余的(具有空语义).在确定覆盖时不考虑访问控制(第11条).
另外,请注意它没有谈论访问规范.因此,重写函数的基类和派生类访问说明符可能不同
这意味着Derived :: eval不会覆盖Base :: eval,因为它们的cv资格不同.
| 归档时间: |
|
| 查看次数: |
10746 次 |
| 最近记录: |