C++对象向下转型异常:C风格转换赋值无效且触发析构函数
问题底层成因
你遇到的异常表现是C++的对象切片规则、临时对象生命周期、C风格转型的默认语义共同作用的结果,具体逻辑如下:
- 首先明确
(A)b = a的执行行为:
C风格对派生类对象做(基类名)类型转换时,默认语义是生成基类值对象而非基类引用,等价于static_cast<A>(b)。这个操作会从b的基类子对象拷贝构造出一个独立的临时A对象,和原b对象完全分离。后续的= a赋值只会修改这个临时对象的值,完全不会影响原b的基类成员,所以你打印b.i还是初始值0。
这个临时对象的生命周期只维持到当前表达式结束,表达式执行完成后临时对象自动销毁,就会触发你看到的那行意外的A destructor called输出。 - 再对比
A& ra = b; ra = a的行为:
这里你显式将ra声明为A类型的左值引用,直接绑定到b自身携带的基类子对象上,后续赋值操作直接作用在b的基类成员上,所以能得到预期的赋值效果,也不会产生额外临时对象,没有多余的析构调用。
默认编译等级下g++不输出告警是符合实现规则的,如果你开启-Weffc++或者-Wconversion这类高等级告警,可能会得到相关提示。
内容的提问来源于stack exchange,提问作者kile
相关产品推荐
相关产品推荐

