对象切片是派生类对象赋值给基类对象时仅保留基类部分、丢失派生成员与多态性的现象,因按类型大小内存拷贝且仅调用基类拷贝构造函数所致;应使用指针/引用、智能指针或禁用基类拷贝操作来避免。

对象切片是指将派生类对象赋值给基类对象(而非指针或引用)时,派生类中新增的成员和行为被“截掉”,只保留基类部分的现象。这会导致信息丢失,且无法多态调用派生类重写的虚函数。
为什么会发生对象切片?
根本原因是C++中对象赋值是按类型大小进行内存拷贝的。基类对象有固定大小,无法容纳派生类额外的数据成员;编译器只调用基类的拷贝构造函数或赋值运算符,跳过派生类部分。
常见触发场景包括:
用派生类对象直接初始化或赋值给基类对象(Base b = Derived();)函数参数按值传递基类类型,却传入派生类对象(void func(Base b); func(d);)容器存储基类对象(如std::vector),插入派生类实例
如何避免对象切片?
核心思路是不直接操作对象实体,而是通过间接方式保留类型信息和多态能力。
立即学习“C++免费学习笔记(深入)”;
用指针或引用代替值传递:函数参数、返回值、容器元素尽量使用Base*或const Base&;现代C++推荐用std::unique_ptr或std::shared_ptr管理堆上派生对象禁用基类的拷贝/赋值操作(可选):在基类中将拷贝构造函数和operator=声明为delete,从语法层面阻止误用避免值语义容器存多态对象:不要用std::vector存派生类对象;改用std::vector>
一个典型错误与修正对比
错误写法:
class Base { public: virtual void say() { cout << "Base"; } };class Derived : public Base { int x = 42; public: void say() override { cout << "Derived"; } };void bad_func(Base b) { b.say(); } // 切片发生,永远输出"Base"Base b = Derived(); // 切片发生,x丢失
正确写法:
void good_func(const Base& b) { b.say(); } // 输出"Derived"void good_func_ptr(const Base* b) { b->say(); }auto ptr = std::make_unique();good_func(*ptr); // 安全调用
基本上就这些。切片不是语法错误,但会悄悄破坏多态逻辑——关键在于养成用引用/智能指针代替值传递的习惯。
以上就是C++中的对象切片(Object Slicing)是什么?(如何避免)的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1488760.html
微信扫一扫
支付宝扫一扫