为什么动态绑定没有按预期运行?

时间:2014-01-22 08:52:10

标签: c++ inheritance dynamic-binding

给定基类和派生类如下:

基地:

class AA
{
public:
    AA() = default;
    virtual void print() const { std::cout << aa << "\n";}

private:
    std::string aa = "AA";
};

派生:

class BB : public AA
{
public:
    BB() = default;
    virtual void print() const override {std::cout << bb << "\n"; }

private:
    std::string bb = "BB";
};

第一次尝试:

int main()
{
    AA aa;  BB bb;
    AA& //r = aa; r.print();

    r = bb;
    r.print();

    return 0;
}

结果正是我的预期:

BB
Press <RETURN> to close this window...

但是//被删除后的第二次尝试:

int main()
{
    AA aa;  BB bb;
    AA& r = aa; r.print();

    r = bb;
    r.print();
 //!^^^^^^^^^^--why wasn't the print in derived class called?
    return 0;
}

输出结果为:

AA
AA
Press <RETURN> to close this window...

如上所述,为什么在执行第二个print时调用派生类中定义的r.print()

2 个答案:

答案 0 :(得分:3)

因为表达式r = bb完全等同于aa = bb。赋值运算符仅将bb类已知的AA部分复制到aa对象中。

换句话说,在分配后,r仍指向aa,这是AA的一个实例。在任何意义上它都 not 指向BB实例。

引用永远不能更改它引用的对象,因此使用引用无法实现预期的行为。为了获得你正在寻找的多态性,你可以使用指针:

AA* p = &aa;
p->print();

p = &bb;
p->print();

答案 1 :(得分:1)

因此:

r = bb;

上述语句不会将引用r绑定(重新绑定?)到bb。相反,它会将AA bb部分复制到aa r,这是{{1}}引用的对象。

为测试上述声明,以下是一个示例:http://coliru.stacked-crooked.com/a/00d20990fe0ddd26