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

使用unique_ptr作为成员时,如何利用编译器生成的拷贝/移动构造函数?

带深拷贝语义的智能指针包装器需求

假设我有一个包含unique_ptr数据成员的类,希望通过深度克隆智能指针指向的对象来让类支持拷贝,示例代码如下:

#include <iostream>
#include <memory>

using namespace std;

class Bar {
public:
    Bar() { cout << "Bar::ctor " << this << '\n'; }
    ~Bar() { cout << "~Bar" << this << '\n'; }
    std::unique_ptr<Bar> clone() const { 
        auto p = std::make_unique<Bar>(*this); 
        cout << "Bar::clone() " << this << " to " << p << '\n';
        return p;
    }
};

class Foo {
public:
    Foo() = default;
    ~Foo() = default;
    Foo(Foo const & other) : p_{other.p_->clone()} { 
        cout << "Foo::copy-ctor " << p_ << ", other.p_ " << other.p_ << '\n';
    }
    Foo(Foo && other) : p_{std::move(other.p_)} {
        cout << "Foo::move-ctor " << p_ << ", other.p_ " << other.p_ << '\n';
    }
    Foo & operator=(Foo const & other) { 
        cout << "Foo::copy-assign " << p_ << ", other._p " << other.p_ << '\n';
        p_ = other.p_->clone(); return *this;
    }
    Foo & operator=(Foo && other) { 
        cout << "Foo::move-assign " << p_ << '\n';
        p_ = std::move(other.p_); return *this; 
    }

    void store(std::unique_ptr<Bar> p) {
        cout << "Foo::store() " << p << '\n';
        p_ = std::move(p);
    }

public:  // 方便后续打印p_
    std::unique_ptr<Bar> p_;
};

std::unique_ptr<Bar> bar() {
    return std::make_unique<Bar>();
}

int main() {
    Foo f;

    auto b = bar();
    cout << "b " << b << '\n';

    f.store(std::move(b));

    cout << "copy" << '\n';
    auto g {f};
    cout << "assign" << '\n';
    Foo h;
    h = f;
    cout << "move" << '\n';
    auto i = std::move(f);

    cout << "f.p_ " << f.p_ << '\n';
    cout << "g.p_ " << g.p_ << '\n';
    cout << "h.p_ " << h.p_ << '\n';
}

程序输出:

Bar::ctor 0x2314eb0
b 0x2314eb0
Foo::store() 0x2314eb0
copy
Bar::clone() 0x2314eb0 to 0x2315ee0
Foo::copy-ctor 0x2315ee0, other.p_ 0x2314eb0
assign
Foo::copy-assign 0, other._p 0x2314eb0
Bar::clone() 0x2314eb0 to 0x2315f00
move
Foo::move-ctor 0x2314eb0, other.p_ 0
f.p_ 0
g.p_ 0x2315ee0
h.p_ 0x2315f00
~Bar0x2314eb0
~Bar0x2315f00
~Bar0x2315ee0

这段代码的核心问题在于:由于unique_ptr的拷贝构造函数被删除,类无法使用= default;生成默认的拷贝/移动构造函数及赋值运算符,必须手动定义这些函数来实现深拷贝语义。

如果只有单个unique_ptr数据成员,手动定义还不算麻烦,但如果给Foo类添加更多数据成员,就需要在四个拷贝/移动构造函数和赋值运算符中显式地拷贝或赋值这些成员——因为一旦手动定义了其中一个特殊成员函数,编译器就不会再生成其他默认的特殊成员函数了,这会让代码很快变得混乱不堪。

我想知道:标准库中是否存在一种unique_ptr的包装器,既能实现自动深拷贝,又能保持const正确性,从而让Foo类可以简化为如下形式,直接复用编译器生成的默认拷贝/移动构造函数和赋值运算符?

class Foo {
public:
    Foo() = default;
    ~Foo() = default;
    Foo(Foo const & other) = default;
    Foo(Foo && other) = default;
    Foo & operator=(Foo const & other) = default;
    Foo & operator=(Foo && other) = default;

    // ...

public:
    DeepCopyUniquePtr p_;  // 这种类型是否存在?
    int a;
    float b; 
    // 更多成员...
    char z;
};

内容的提问来源于stack exchange,提问作者davidA

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 01:12:55