共享指针属性复制问题: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
相关产品推荐
相关产品推荐

