std::unique_ptr移动时如何置空另一指针?模板类私有成员访问解惑
问题解析:std::unique_ptr如何跨模板实例访问私有成员?
当执行移动操作时,通常会将被移动对象的内部指针置空,std::unique_ptr也遵循这个逻辑。它的赋值运算符是模板化设计,支持不同类型(比如派生类)的unique_ptr之间的移动操作。但这里有个疑问:模板实例化后的不同类型(比如std::unique_ptr<B>和std::unique_ptr<D>)属于完全不同的类,按默认规则无法互相访问私有成员,那std::unique_ptr是怎么做到修改另一个实例的私有指针的?
问题根源
你自己实现的MyPointer类编译失败,正是因为MyPointer<B>和MyPointer<D>是两个独立的类,MyPointer<B>的移动赋值运算符无法直接访问MyPointer<D>的私有成员pointer。
std::unique_ptr的解决思路:模板友元
std::unique_ptr的实现中,会在类内部声明模板友元,让所有unique_ptr的实例化类型都互为友元,从而允许互相访问私有成员。
修改你的实现示例
给MyPointer添加模板友元声明后,就能解决跨实例访问私有成员的问题:
template <typename T> class MyPointer { // 声明所有MyPointer<U>实例都是当前MyPointer<T>的友元 template <typename U> friend class MyPointer; public: template <typename U> void operator=(const MyPointer<U>& other) = delete; template <typename U> void operator=(MyPointer<U>&& other) { // 现在可以正常访问other的私有成员pointer了 other.pointer = nullptr; } char* get() const { return pointer; } private: char* pointer = nullptr; // 初始化避免野指针 }; int main() { struct B {}; struct D : B {}; std::unique_ptr<B> base; std::unique_ptr<D> derived; // std::unique_ptr正常执行移动 base = std::move(derived); MyPointer<B> my_pointer_b; MyPointer<D> my_pointer_d; // 现在可以正常编译执行移动操作 my_pointer_b = std::move(my_pointer_d); }
补充说明
模板友元的作用范围是:对于任意的T和U,MyPointer<T>和MyPointer<U>互为友元,因此它们的成员函数可以互相访问对方的私有/保护成员。这正是std::unique_ptr能在移动操作中修改另一个实例内部指针的核心原因。
内容的提问来源于stack exchange,提问作者Zebrafish
相关产品推荐
相关产品推荐

