派生类对象赋值疑问:为何代码输出14而非34?
同派生类对象赋值:为何输出14而非34?
核心原因是编译器为派生类B生成了默认赋值运算符,这个默认运算符的行为是:
- 首先调用基类
A的自定义赋值运算符处理基类成员na - 然后对派生类自身的成员
nb执行逐成员复制
代码执行过程拆解
- 初始化对象时:
b1:nb=1(构造函数参数i=1),na=2(基类构造函数参数j=2)b2:nb=3(构造函数参数i=3),na=4(基类构造函数参数j=4)
- 执行
b2 = b1时:- 因为
B没有自定义operator=,编译器生成的默认版本先调用A::operator=(const A&):将b1.na的值(2)乘以2,赋值给b2.na,所以b2.na变为4 - 接着默认运算符会直接把
b1.nb的值(1)赋值给b2.nb,覆盖了b2原本的nb=3
- 因为
- 最后输出
b2.nb和b2.na,结果就是14
如何自定义派生类的赋值行为
如果不想让nb被默认复制,或者需要自定义赋值逻辑,你需要在B中显式重载赋值运算符:
class B : public A{ public: B(int i, int j): A(j){nb = i;} int nb; // 自定义派生类赋值运算符 B& operator=(const B& b) { if (this != &b) { // 防止自赋值 A::operator=(b); // 调用基类赋值运算符处理na // 这里可以自定义nb的赋值逻辑,比如保留原有值: // nb = nb; // 或者直接不写这行,nb就不会被修改 // 如果要和默认行为一致,就写 nb = b.nb; } return *this; } };
内容的提问来源于stack exchange,提问作者bjosujs
相关产品推荐
相关产品推荐

