我有一个关于共享指针的快速问题,因为我面临与共享指针相关的问题。 我有一个名为 Cube 的共享指针,它有一个 Vector3d 的共享指针向量。
我想要做的是创建另一个 Cube 对象,该对象具有与 Vector3d 相同的共享指针向量,因此它们具有相同的Vector3d相同的向量。但是,当我这样做时,它会为第二个 Cube 对象的向量中的每个 Vector3d 创建一个引用。这意味着每当我更改第二个多维数据集中的点时,它也会更改第一个多维数据集中的所有Vector3d。
多维数据集类:
class Cube
{
public:
Cube();
~Cube();
std::vector<std::shared_ptr<CVector3d>> vectors;
void calculate_center();
double center_x;
double center_y;
double center_z;
std::vector<int> indices;
void transform(std::shared_ptr<CMatrix3d> transformation_matrix);
};
Cube对象和Vector3d集合的分配:
std::shared_ptr<GameObject> cube_3d = std::make_shared<Cube>();
cube_3d->vectors.push_back(std::make_shared<CVector3d>(300, 100, 0)); //front top left
cube_3d->vectors.push_back(std::make_shared<CVector3d>(300, 100, -200)); //back top left
cube_3d->vectors.push_back(std::make_shared<CVector3d>(500, 100, -200)); //back top right
cube_3d->vectors.push_back(std::make_shared<CVector3d>(500, 100, 0)); //front top right
cube_3d->vectors.push_back(std::make_shared<CVector3d>(300, 300, 0)); //front bottom left
cube_3d->vectors.push_back(std::make_shared<CVector3d>(300, 300, -200)); //back bottom left
cube_3d->vectors.push_back(std::make_shared<CVector3d>(500, 300, -200)); //back bottom right
cube_3d->vectors.push_back(std::make_shared<CVector3d>(500, 300, 0)); //front bottom right
std::shared_ptr<GameObject> projection_cube_3d = std::make_shared<Cube>();
projection_cube_3d->vectors = cube_3d->vectors;
我如何解决这个问题,这是我的代码中的设计缺陷吗?
提前致谢!
编辑1:添加了实际的代码段
答案 0 :(得分:-1)
代码projection_cube_3d->vectors = cube_3d->vectors;
执行复制分配,用另一个向量的内容副本替换向量的内容。换句话说,cube_3d->vectors
中的每个shared_ptr都会复制到projection_cube_3d->vectors
中。当然,复制shared_ptr并不会创建shared_ptr指向的对象的副本,这两个指针指向同一个对象(首先是shared_ptr的整个点)。
您要做的是创建每个CVector3D的副本。您可以使用以下代码执行此操作:
for (auto& ptr : cube_3d->vectors)
projection_cube_3d->vectors.push_back(std::make_shared<CVector3D>(*ptr))
代码std::make_shared<CVector3D>(*ptr)
创建一个新的CVector3D,它是*ptr
的副本,并将指针包装到shared_ptr中的新对象,然后将其推入向量中。
正如评论中所指出的,你应该考虑为Cube编写一个拷贝构造函数,它可以执行深拷贝而不是浅拷贝。另请注意,只有在需要表达共享所有权时,才应使用shared_ptr。在您的情况下,我不相信这是必要的,例如,您希望每个多维数据集都存储自己的CVector3D
。如果您打算以多态方式使用此对象(例如,它具有不同行为的子类),或者它是一个大而复杂的对象,您真的不希望它被复制,那么使用指向CVector3D的指针也是有意义的。周围。对于像vector3d这样的原始类型来说,这种情况很少发生,因此您可能不需要指针。 std::vector<CVector3D>
会更好,在这种情况下,将一个矢量复制到另一个矢量会自动完成您想要的操作。