C++代码非多态行为的原因解析
解释C++代码中非多态行为的原因
核心原因:对象切片(Object Slicing)
你的代码里出现两种不同行为的关键在于对象赋值时的切片问题,我们分别拆解两种场景:
基类指针指向派生类对象(多态生效)
Base* bp = new Derived(); bp->hello(); // 输出 Hello Derived这里用基类指针指向派生类对象时,C++的虚函数机制会生效:指针会关联到派生类对象的虚函数表,调用
hello()时会动态派发给派生类的重写版本,所以表现出多态行为。派生类对象赋值给基类对象(切片发生,多态失效)
Base b = Derived(); b.hello(); // 输出 Hello Base当你把一个
Derived对象直接赋值给Base类型的对象时,会触发对象切片:编译器只会把Derived对象中属于Base的部分复制到b中,Derived类自己独有的成员(包括虚函数表中指向派生类hello()的条目)都会被“切掉”。最终b是一个纯粹的Base对象,调用hello()时会直接绑定到Base类的版本,完全不会触发多态。
为什么没有编译器警告/错误?
这是C++标准允许的合法行为,默认情况下-Wall选项不会开启对象切片的警告。如果想要检测这类问题,可以给GCC添加-Wobject-slicing编译选项,此时编译器会针对派生类对象赋值给基类对象的行为发出警告。
内容的提问来源于stack exchange,提问作者Morten
相关产品推荐
相关产品推荐

