如何通过公共方法交换类中私有unique_ptr的所有权?
实现方案
首先明确核心需求:通过类的公共成员函数,交换两个对象内部嵌套的unique_ptr<C>所有权;同时处理vector<unique_ptr<A>>中元素的内部成员交换。以下是具体实现:
1. 修正类B的swap函数
类B需要提供公共接口交换内部的unique_ptr<C>,参数必须是非const引用(因为要修改传入对象的成员):
#include <memory> class C {}; // 假设C是多态基类,已有派生类实现 class B { // B是多态类型 private: std::unique_ptr<C> c; public: // 暴露交换c所有权的公共接口 void swap_c(B& other) { // 直接调用unique_ptr的swap成员,安全处理空指针 c.swap(other.c); } // 可选:为了符合STL习惯,也可以实现非成员swap函数(推荐) friend void swap(B& lhs, B& rhs) { lhs.swap_c(rhs); } };
2. 实现类A的swap_b函数
类A通过调用B的swap接口,完成内部b.c的所有权交换:
class A { // A是多态类型,派生类A1、A2等 private: std::unique_ptr<B> b; public: // 交换两个A对象内部的b.c所有权 void swap_b(A& other) { // 若业务允许空指针,可跳过检查;否则需确保b和other.b有效 if (b && other.b) { b->swap_c(*other.b); } // 或者直接调用(unique_ptr空指针swap安全): // b->swap_c(*other.b); } // 可选:同样实现非成员swap函数,适配STL场景 friend void swap(A& lhs, A& rhs) { lhs.swap_b(rhs); } };
3. 主函数及vector场景的调用
注意区分unique_ptr自身的swap(交换指针所有权)和自定义的swap_b(交换内部成员):
#include <vector> int main() { // 单个对象的内部成员交换 std::unique_ptr<A> alphaOne = std::make_unique<A1>(...); std::unique_ptr<A> alphaTwo = std::make_unique<A2>(...); // 交换alphaOne和alphaTwo内部的b.c所有权(不是交换unique_ptr<A>本身) alphaOne->swap_b(*alphaTwo); // vector<unique_ptr<A>>场景的内部成员交换 std::vector<std::unique_ptr<A>> vec; vec.push_back(std::make_unique<A1>(...)); vec.push_back(std::make_unique<A2>(...)); // 交换vec中第0和第1个元素的内部b.c所有权 vec[0]->swap_b(*vec[1]); }
关键注意点
- 参数必须用非const引用:值传递会导致对象拷贝,无法修改原对象的成员;const引用则不允许修改成员,都不符合swap的需求。
- 空指针处理:
unique_ptr的swap对空指针是安全的,若你的业务逻辑允许b或other.b为空,可直接调用swap_c无需检查;若要求指针必须有效,则需添加空指针判断避免崩溃。 - 非成员swap函数(可选):实现友元版的非成员
swap,可以让你的类更好地适配STL的算法(比如std::swap会优先调用自定义的非成员swap)。
内容的提问来源于stack exchange,提问作者ajsdiubfaoishd
相关产品推荐
相关产品推荐

