You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 09:35:11