如何实现包含unique_ptr的类的深拷贝?(含map场景示例)
实现包含std::unique_ptr的类的深拷贝
因为std::unique_ptr是独占式智能指针,不支持拷贝操作,所以包含它的容器(比如你的testMap)也无法默认完成拷贝,这直接导致test类的默认拷贝构造函数被编译器自动删除。要实现深拷贝,必须手动编写拷贝构造函数,对每个unique_ptr指向的对象进行递归深拷贝。
具体实现步骤
- 拷贝普通成员
map1:sMap是std::unordered_map<std::string, std::string>,它的拷贝构造默认支持,直接初始化即可。 - 遍历源对象的
map2:对每个键值对,取出unique_ptr指向的test对象,调用test的拷贝构造函数创建新实例,再用std::make_unique包装成新的unique_ptr,最后插入到当前对象的map2中。
修改后的完整代码
#include <iostream> #include <unordered_map> #include <string> #include <memory> class test; typedef std::unordered_map<std::string, std::string> sMap; typedef std::unordered_map<std::string, std::unique_ptr<test>> testMap; class test { public: sMap map1; testMap map2; test() = default; // 手动实现深拷贝构造函数 test(const test& t) : map1(t.map1) // 直接拷贝普通map { // 遍历源对象的map2,逐个深拷贝每个test对象 for (const auto& pair : t.map2) { // 对pair.second指向的test对象进行深拷贝,创建新的unique_ptr map2.emplace(pair.first, std::make_unique<test>(*pair.second)); } } // 遵循三/五法则,同时实现拷贝赋值运算符 test& operator=(const test& t) { if (this != &t) { map1 = t.map1; map2.clear(); for (const auto& pair : t.map2) { map2.emplace(pair.first, std::make_unique<test>(*pair.second)); } } return *this; } }; int main() { sMap myMap; myMap["a"] = "b"; std::unique_ptr<test> tobj= std::make_unique<test>(); test& obj = *tobj; obj.map1 = myMap; test obj2; obj2.map2.emplace("one", std::move(tobj)); test obj3(obj2); // 现在可以正常调用拷贝构造 // 验证深拷贝:修改obj2中的对象不会影响obj3 obj2.map2["one"]->map1["a"] = "c"; std::cout << obj3.map2["one"]->map1["a"] << std::endl; // 输出b,确认是深拷贝 return 0; }
关键说明
- 递归深拷贝:由于
test类的map2包含unique_ptr<test>,拷贝构造函数会递归调用自身,完成嵌套对象的深拷贝,这正是深拷贝需要的行为。 - 三/五法则:手动实现拷贝构造函数后,建议同时实现拷贝赋值运算符,保证类的行为符合C++的资源管理规则。如果需要移动语义,还可以补充实现移动构造和移动赋值运算符。
内容的提问来源于stack exchange,提问作者Trl
相关产品推荐
相关产品推荐

