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

共享指针属性复制问题:Cube对象的Vector3d共享指针向量复制异常

解决共享指针拷贝Cube对象的问题

看起来你对shared_ptr的拷贝行为有点困惑,我来帮你理清楚两种不同需求下的实现方式:


需求1:让两个Cube共享同一个Vector3d实例(你原本描述的期望)

如果你的目标是让新Cube和原Cube的vector里的shared_ptr都指向同一个Vector3d对象,那其实shared_ptr的默认拷贝行为就已经满足你的需求了。因为当你拷贝shared_ptr<Vector3d>时,它会自动增加引用计数,两个指针共享底层的Vector3d实例。

举个代码例子:

#include <vector>
#include <memory>

class Vector3d {
public:
    double x, y, z;
    Vector3d(double x_, double y_, double z_) : x(x_), y(y_), z(z_) {}
};

class Cube {
public:
    std::vector<std::shared_ptr<Vector3d>> points;
    
    // 拷贝构造函数,默认的就足够,因为它会拷贝整个vector,里面的shared_ptr也会被正确拷贝
    Cube(const Cube& other) = default;
};

// 使用示例
int main() {
    // 创建原Cube并添加点
    auto originalCube = std::make_shared<Cube>();
    originalCube->points.push_back(std::make_shared<Vector3d>(1,2,3));
    originalCube->points.push_back(std::make_shared<Vector3d>(4,5,6));
    
    // 创建新Cube,直接拷贝原Cube的内容
    Cube newCube = *originalCube;
    
    // 修改新Cube里的一个点的坐标,原Cube的对应点也会改变,因为它们共享同一个实例
    newCube.points[0]->x = 100;
    // 此时 originalCube->points[0]->x 也会是100,符合你的需求
    return 0;
}

这种情况下,两个Cube的vector里的shared_ptr指向同一个Vector3d实例,修改其中一个的内容,另一个也会看到变化——这就是shared_ptr的核心特性,共享所有权。


需求2:让两个Cube拥有独立的Vector3d实例(你可能实际想要的?)

如果你发现修改新Cube的点会影响原Cube,而这不是你想要的,那说明你需要的是深度拷贝:创建新的Vector3d实例,而不是共享原有的。这时候你需要自定义Cube的拷贝构造函数,手动遍历每个shared_ptr,创建新的Vector3d对象:

class Cube {
public:
    std::vector<std::shared_ptr<Vector3d>> points;
    
    // 自定义拷贝构造函数,实现深度拷贝
    Cube(const Cube& other) {
        points.reserve(other.points.size());
        for (const auto& ptr : other.points) {
            // 创建新的Vector3d实例,拷贝原实例的内容
            points.push_back(std::make_shared<Vector3d>(*ptr));
        }
    }
    
    // 别忘了拷贝赋值运算符(遵循三/五法则)
    Cube& operator=(const Cube& other) {
        if (this != &other) {
            points.clear();
            points.reserve(other.points.size());
            for (const auto& ptr : other.points) {
                points.push_back(std::make_shared<Vector3d>(*ptr));
            }
        }
        return *this;
    }
    
    // 移动构造和移动赋值可以默认
    Cube(Cube&&) = default;
    Cube& operator=(Cube&&) = default;
};

这样当你创建新Cube时,新的vector里的每个shared_ptr都指向一个独立的Vector3d实例,修改新Cube的点不会影响原Cube。


总结一下

  • 如果你想共享Vector3d实例:直接使用默认的拷贝构造/赋值,shared_ptr会自动处理引用计数。
  • 如果你想独立的Vector3d实例:自定义拷贝构造和赋值运算符,手动创建新的Vector3d对象。

你可以根据自己的实际需求选择对应的实现方式~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:31:34