c++ - 为什么动态绑定(bind)没有按预期运行?

标签 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...

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

最佳答案

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

也就是说,赋值后,r仍然指向aa,它是AA的一个实例。它在任何意义上都指向BB 实例。

引用永远不会改变它引用的对象,因此无法通过引用实现预期的行为。要获得您正在寻找的多态性,您可以使用指针:

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

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

关于c++ - 为什么动态绑定(bind)没有按预期运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21278170/

相关文章:

c++ - 生成 m 和 n 之间的素数

c++ - 在 C++ 的受控环境中执行 Windows 命令

asp.net - Gridview 行编辑 - 动态绑定(bind)到 DropDownList

c# - 如何避免转换器与后面的 WPF 代码中的多重绑定(bind)发生冲突

c++ - 调试错误 -Abort() 已被调用

c++ - 删除 vector 元素导致程序崩溃

java - 为什么我允许 "direct access"到对象的 protected 字段,该对象的类是在不同的包中定义的?

Javascript 继承依赖于构造函数参数

java - Java 中的引用父 UI 元素

C++ Mixin - 初始化期间的动态绑定(bind)习语