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



给定基类和派生类如下:

底座:

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

因为这个:

r = bb;

上述语句不绑定(重新绑定?)引用rbb。相反,它将bbAA部分复制到aar引用的对象。

为了测试上述说法,这里有一个例子:http://coliru.stacked-crooked.com/a/00d20990fe0ddd26

相关内容

  • 没有找到相关文章

最新更新