C++ 为什么没有';动态绑定的行为是否符合预期?

C++ 为什么没有';动态绑定的行为是否符合预期?,c++,inheritance,dynamic-binding,C++,Inheritance,Dynamic Binding,给定基类和派生类,如下所示: 基地: class AA { public: AA() = default; virtual void print() const { std::cout << aa << "\n";} private: std::string aa = "AA"; }; 结果正是我所期望的: BB Press <RETURN> to close this window... 结果是: AA AA Press <

给定基类和派生类,如下所示:

基地:

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

private:
    std::string aa = "AA";
};
结果正是我所期望的:

BB
Press <RETURN> to close this window...
结果是:

AA
AA
Press <RETURN> to close this window...
AA
AA
按以关闭此窗口。。。

如上所述,为什么在执行第二个
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
完全等同于
aa=bb
。赋值运算符仅将
AA
类已知的
bb
部分复制到
AA
对象中

换句话说,在赋值之后,
r
仍然指向
aa
,这是
aa
的一个实例。它不指向任何意义上的
BB
实例

引用永远无法更改它引用的对象,因此无法通过引用实现预期的行为。要获得所需的多态性,您需要使用指针:

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

p = &bb;
p->print();
因此:

r = bb;
上述语句不将参考
r
绑定到
bb
。相反,它将
AA
部分
bb
复制到
AA
中,后者是
r
引用的对象

为了测试上述声明,这里有一个例子:

,因为:

r = bb;
上述语句不将参考
r
绑定到
bb
。相反,它将
AA
部分
bb
复制到
AA
中,后者是
r
引用的对象


为了检验上述说法,这里有一个例子:

所以实际上语句
r=bb
通过复制object的sub-object
bb
改变了
aa
的值,不是吗?我不确定我是否遵循了“object的subject”术语,但是是的:
r=bb
只是运行
aa.aa::operator=(bb)
,这反过来又将
AA
-部分
bb
复制到
AA
中。对不起,我的拼写很愚蠢,我应该作为子对象来写。我不知道为什么我不能以你的名字user4815162342.@Alan.W你不能给我添加通知,因为这是不必要的-因为你在评论我的答案,我会自动得到通知。这就是为什么当一个类被设计为用作基础时,你通常会禁用赋值。所以实际上,语句
r=bb
通过将object
bb
的子对象复制到它来改变
aa
的值,不是吗?我不确定我是否遵循了“object的主题”术语,但是是的:
r=bb
只是简单地运行
aa.aa::operator=(bb)
,然后将
bb
aa
部分复制到
aa
中。对不起,我的拼写很愚蠢,我本应该以子对象的身份编写..但不知道为什么我不能以您的用户名user4815162342..@Alan.W您不能向我添加通知,因为这是不必要的-因为您正在评论我的答案,所以我会自动收到通知。这就是为什么当类被设计为用作基时,您通常会禁用赋值。@Alan.W这是最重要的中的“标准”联机编译器,尽管您可以在中找到更多。@Alan.W它是中的“标准”联机编译器,尽管您可以在中找到更多。
r = bb;