当前位置: 首页 > news >正文

【C++】多态对象拷贝

C++11 以后,STL 容器(如:vector、list、map)的插入类接口(push_back、insert、emplace_back等)都增加了右值引用版本。比如:vector::push_back(T&& val),当传入右值时将不再进行拷贝,而是移动。

使用多态时,通过Base的指针或引用指向具体子类。在容器中,以Base类型存储,比如:vector<Base*> vec

我现在期望对vec中的每个对象,都按照其【实际的类型】进行拷贝,怎么做?拷贝构造函数又不可以设为virtual,从而进行多态实施具体行为。

  • 设一个virtual Clone(),让具体的类自己负责自己具体的类型。这是多态拷贝的标准解决方案

  • 析构函数一定要设为virtual

  • 这是原型模式(prototype pattern)的思想

  • C++支持协变返回类型

    也就是virtual Clone接口,可以返回具体类型的指针或引用,而不是只返回Base*

    • C++允许的协变返回类型仅限于原始指针和引用,不适用于智能指针

    • 智能指针和协变两者不兼容的话,在安全性(裸指针or智能指针)、类型信息缺失之间做选择,该如何取舍?

      以安全性为前提,优先使用智能指针,类型信息可通过dynaminc_cast转。

      如果类型是当前关键需求,必须使用协变,可使用【裸指针+RAII】的方式,在类析构里

    class Base
    {virtual Base* Clone()=0;	//定义Clone接口
    }class Son1:public Base
    {Son1(){}Son1(const Son1& another){}	//拷贝构造//virtual Base* Clone() const overridevirtual Son1* Clone() const override   //C++支持协变返回类型,可以返回更具体的指针,返回Son1*而不是Base*{return new Son1(*this);	//将当前对象传给本类的拷贝构造,从而返回一个本类的深拷贝对象}
    }class Son2:public Base
    {Son2(){}Son2(const Son2& another){}	//拷贝构造virtual Son2* Clone() const override{return new Son2(*this);	}
    }int main()
    {std::vector<Base*> vec;vec.push_back(new Son1);vec.push_back(new Son2);std::vector<Base*> vecCopy;for(const auto& item:vec){vecCopy.push_back(item.Clone());	//返回深拷贝对象,push_back到vecCopy中}
    }
    
  • 使用智能指针管理所有权

    防止Clone()中new出来的对象忘记delete。

    class Base
    {virtual std::unique_ptr<Base> Clone() const = 0;	
    }class Son1:public Base
    {Son1(){}Son1(const Son1& another){}	virtual std::unique_ptr<Base> Clone() const override   //不能写成std::unique_ptr<Son1>,智能指针不支持协变{//unique_ptr不允许拷贝,但编译器允许返回右值的unique_ptr。而c++中规定:return的局部变量当作右值处理//因此返回的是一个右值unique_ptr对象,传入到vec::push_back时,由于C++11起push_back(所有stl容器的插入接口)//有了参数为右值的重载:push_back(T&& value)触发push_back的移动return std::make_unique<Son1>(*this);	}
    }class Son2:public Base
    {Son2(){}Son2(const Son2& another){}	virtual std::unique_ptr<Base> Clone() const override{return std::make_unique<Son2>(*this);	}
    }int main()
    {std::vector<std::unique_ptr<Base>> vec;vec.push_back(std::make_unique<Son1>());vec.push_back(std::make_unique<Son2>());std::vector<std::unique_ptr<Base>> vecCopy;for(const auto& item:vec){vecCopy.push_back(item->Clone());	//返回右值unique_ptr,调用右值重载}
    }
    
  • 更高级实现:CRTP

http://www.jsqmd.com/news/378887/

相关文章:

  • 百考通:双维降重神器,让论文轻松通关AIGC与重复率双重检测!
  • 2026年口碑好的高性能电动车型驱动电机超薄电机绝缘/人形机器人超薄电机绝缘怎么选真实参考销售厂家参考 - 行业平台推荐
  • 百考通期刊论文智能生成系统:让高水平学术发表不再是难题
  • 完整教程:微软 Agent Framework:构建、编排和部署 AI 代理的全面框架
  • 闭眼入!8个一键生成论文工具测评:专科生毕业论文+科研写作全攻略
  • php crm客户属性字段变更记录:业务合规与数据可信的核心保障
  • AlphaFold破解心脏病关键蛋白结构
  • 百考通实践报告智能生成:让实习成果专业呈现,轻松斩获导师好评!
  • 【超全】基于微信小程序的居住证申报系统【包括源码+文档+调试】
  • 2026年知名的新型建材更新厂家选择指南哪家好 - 行业平台推荐
  • 隧道开挖flac-pfc耦合,包含平衡开挖部分 如图,隧道衬砌外面是pfc的ball与wall...
  • 百考通答辩PPT生成:智能定制,让答辩轻松通关!
  • 2026年评价高的上海办公装饰设计/办公室装潢设计口碑排行精选供应商推荐 - 行业平台推荐
  • 2026培育钻石品牌价值排行榜:基于五大维度的科学测评,谁是真正的“质价比”之王? - 品牌企业推荐师(官方)
  • 百考通任务书智能生成:让学术研究从“第一份文件“就专业规范!
  • 2026年口碑好的蔬菜食品包装机/生鲜食品包装机哪家强公司实力参考(精选) - 行业平台推荐
  • 2026年深度解析山东昊丰密封件有限公司:一家新兴密封科技制造商的成长路径与核心优势 - 品牌推荐
  • 闲置微信立减金别浪费!微信立减金回收有3种实用方法,新手零门槛变现不踩坑 - 京回收小程序
  • 百考通AIGC检测:学术诚信的“火眼金睛”,让AI辅助写作安全无忧!
  • 2026年评价高的橱柜柜内灯/免焊接柜内灯实力厂家推荐如何选 - 行业平台推荐
  • 百考通:一键生成专业文献综述,让学术研究事半功倍!
  • 百考通:开题报告智能生成,让学术研究从“第一关“就赢在起跑线!
  • 2026年深度解析山东昊丰密封件有限公司:一家新兴密封科技制造商的硬件实力与产能布局 - 品牌推荐
  • 2026年深度解析山东昊丰密封件有限公司:一家新兴科技制造商的产业链布局与风险考量。 - 品牌推荐
  • 2026年热门的滚筒式抛丸机/履带式抛丸机实力厂家 - 行业平台推荐
  • 健身鱼油哪个牌子纯度最高效果好?2026高纯鱼油实测排行榜,全人群适配必看 - 资讯焦点
  • 告别35岁焦虑,开启睡后收入
  • 2026年面向高二毕业生的大学本科预科班推荐,适合高中生的国际预科项目解析 - 品牌2025
  • 2026年口碑好的环保母婴板/全屋定制母婴板选哪家高口碑品牌参考 - 行业平台推荐
  • 什么品牌的鱼油好?2026中老人适合的鱼油品牌排行榜推荐,不踩坑养护首选 - 资讯焦点