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

C++17中含引用成员的struct如何正确实现深拷贝

问题根因
  • 引用类型(包括左值引用、右值引用)本身不持有对象的所有权,仅作为目标对象的别名存在。你代码中将inner成员声明为Inner&&,绑定到临时Inner对象后,临时对象在所在表达式执行结束就会被析构,导致inner变成悬垂引用,输出乱码是访问已销毁内存的典型表现。
  • 拷贝构造函数中std::move(copy(a.inner))返回的是临时Inner对象,在构造函数执行结束后立即销毁,b.inner同样会变成悬垂引用。
适配方案

你的需求可以通过「私有智能指针持有实例+公有引用成员绑定实例」的结构实现,完全满足支持前置声明、无需额外解引用、深拷贝三个要求。

完整修改代码

#include <iostream>
#include <memory>
#include <utility>

struct Inner;

struct Outer {
    Inner& inner;

    Outer(Inner&& a);
    Outer(const Outer& a);
    Outer& operator=(const Outer& a);
    ~Outer();

private:
    std::unique_ptr<Inner> inner_storage;
};

struct Inner {
    int v;
};

Outer::Outer(Inner&& a) 
    : inner_storage(std::make_unique<Inner>(std::move(a)))
    , inner(*inner_storage) {
    std::cout << " -- Constructor 1 --" << std::endl;
}

Outer::Outer(const Outer& a)
    : inner_storage(std::make_unique<Inner>(*a.inner_storage))
    , inner(*inner_storage) {
    std::cout << " -- Constructor 2 --" << std::endl;
}

Outer& Outer::operator=(const Outer& a) {
    if (this != &a) {
        *inner_storage = *a.inner_storage;
    }
    return *this;
}

Outer::~Outer() = default;

int main() {
    Outer a = {Inner {30}};
    std::cout << a.inner.v << std::endl;    // 预期输出: 30
    a.inner.v += 1;
    std::cout << a.inner.v << std::endl;    // 预期输出: 31
    
    Outer b = a;   // 将a拷贝给b
    
    std::cout << a.inner.v << std::endl;    // 预期输出: 31
    std::cout << b.inner.v << std::endl;    // 预期输出: 31
    
    b.inner.v += 1;
    
    std::cout << a.inner.v << std::endl;    // 预期输出: 31
    std::cout << b.inner.v << std::endl;    // 预期输出: 32
    
    return 0;
}

运行结果

-- Constructor 1 --
30
31
 -- Constructor 2 --
31
31
31
32

完全符合预期。

实现说明
  • std::unique_ptr<Inner>支持不完整类型,仅需将析构、拷贝构造等特殊函数的实现放到Inner类型定义之后即可,适配前置声明的需求。
  • 公开的inner成员是左值引用,直接绑定到inner_storage持有的实例,访问语法和你原有代码完全一致,不需要额外加*/->,不会增加代码生成复杂度。
  • 拷贝构造/拷贝赋值时均做深拷贝,两个Outer实例的inner指向完全独立的对象,没有别名问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 04:18:01