C++虚拟Const函数

q09*_*987 6 c++

鉴于以下代码段,

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()?

谢谢

Jos*_*shD 8

在你的Derived类中,eval的原型与虚拟函数的原型不匹配Base.所以它不会覆盖虚函数.

Base::eval() const;
Derived::eval(); //No const.
Run Code Online (Sandbox Code Playgroud)

如果添加const Derived::eval(),则应该获得虚拟行为.


Tho*_*day 8

你可以在脑海中翻译:

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)

并通过检查看到第二个符号与第一个符号的匹配程度.


shu*_*e87 6

这是因为一个声明为const而另一个声明为const.一个功能被另一个隐藏.Derived中的函数将其隐藏在Base中,因为它们具有相同的名称,而它们不是同一个函数.

我的编译器在这里发出警告,你的吗?


Chu*_*dad 5

$ 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资格不同.