C++中如何将含unique_ptr的对象移入vector避免报错
问题解答
持有std::unique_ptr成员的对象完全可以被移入同类型元素的std::vector容器,核心是使用C++移动语义,避免触发拷贝操作。
原理说明
std::unique_ptr是独占所有权的智能指针,它的拷贝构造函数、拷贝赋值运算符被显式删除,不支持拷贝操作,但原生支持移动语义。
只要你没有为类A显式删除移动构造/移动赋值运算符,也没有因为自定义拷贝操作、析构函数等逻辑导致编译器抑制默认移动语义生成,编译器会自动为A生成默认的移动构造和移动赋值函数,自动完成内部unique_ptr成员的所有权转移。
正确实现代码
直接使用std::move将待插入的左值对象转为右值,调用vector的push_back或者emplace_back触发移动插入即可:
#include <vector> #include <memory> // 前置声明someData类型,实际使用时替换为真实定义 struct someData; class A { public: std::unique_ptr<someData> ptr; }; int main() { std::vector<A> objects; A myObject; // 给myObject的ptr赋值,实际业务中替换为你的初始化逻辑 myObject.ptr = std::make_unique<someData>(); // 核心:用std::move转右值,触发移动语义插入 objects.push_back(std::move(myObject)); // 等价写法:objects.emplace_back(std::move(myObject)); return 0; }
关键注意事项
- 移动操作完成后,原对象
myObject处于有效但状态未指定的状态:它内部的ptr已经变为空指针,后续不要对myObject.ptr做解引用操作,否则会触发空指针访问错误。 - 如果你为类
A自定义了拷贝构造、拷贝赋值运算符、析构函数,编译器不会自动生成移动语义,此时需要手动实现移动构造和移动赋值运算符,示例:
class A { public: std::unique_ptr<someData> ptr; A() = default; ~A() { /* 自定义清理逻辑 */ } // 手动实现移动构造 A(A&& other) noexcept : ptr(std::move(other.ptr)) { // 其他自定义成员的移动逻辑 } // 手动实现移动赋值 A& operator=(A&& other) noexcept { if (this != &other) { ptr = std::move(other.ptr); // 其他自定义成员的移动赋值逻辑 } return *this; } // 拷贝操作显式删除,和unique_ptr的独占语义保持一致 A(const A&) = delete; A& operator=(const A&) = delete; };
- 禁止直接对
myObject做拷贝操作(比如直接写objects.push_back(myObject)),该操作会尝试拷贝内部的unique_ptr,直接触发编译错误。
内容的提问来源于stack exchange,提问作者Thicc Theo
相关产品推荐
相关产品推荐

