我想在C ++中设计一个名为Entity的类。该实体具有指向Vector3D成员的指针,Vector3D是3D空间中实体的位置。构造函数允许将Vector3D类型的指针传递给构造函数,以便在类之外实例化Vector3D实例。
因为存在指向动态分配对象的指针,所以必须重载复制构造函数和赋值运算符以深度复制向量。但是,因为向量可以在构造函数中传递,所以它也可以在别处使用,因此不能在析构函数中删除。但是,如果通过复制构造函数创建新实体或使用=运算符赋值,则实体类必须删除vector实例,因为它已在Entity类中实例化。
解决此类问题的最佳方法是什么?
#ifndef ENTITY_H
#define ENTITY_H
#include "Vector3D.h"
class Entity {
public:
Entity(Vector3D*);
Entity(const Entity&);
~Entity();
Entity& operator = (const Entity&);
protected:
Vector3D* vector;
};
#endif
答案 0 :(得分:3)
最好的方法是不使用指向Vector3D
的指针,而是按值取值。如果Vector3D
是我怀疑的(包含3个浮点数或整数的包装),那么分享它并没有太多的好处。
您还可以开始更多地了解所有权以及在客户端代码上破坏Vector3D
的负担(构建Entity
的代码)。
如果这不是一个选项,您可以使用std::shared_ptr。
#include <memory>
struct Vector3D {};
struct Entity {
// Construct from another shared_ptr.
Entity(std::shared_ptr<Vector3D> v) : v_(v) {}
// Assume ownership of `v`.
Entity(Vector3D* v) : v_(v) {}
// depending on which guarantees we have for sharing the vector
// we can omit checks for null.
const Vector3D& vector() const { return v_.get(); }
Vector3D& vector() { return v_.get(); }
private:
std::shared_ptr<Vector3D> v_;
};
答案 1 :(得分:1)
这是使用新的C ++ 11智能指针的完美示例。如果假定客户端代码与Entity
共享所有权,并且可能使用的时间超过Entity
的生命周期,则使用std::shared_ptr
。
如果您明确要将所有权转移到Entity
,即客户端代码在将其包装到Entity
后不再使用该向量,则使用std::unique_ptr
。
如果客户端代码仍然是唯一所有者,从而决定何时删除该向量,则使用std::weak_ptr
。
例如,请参阅http://en.cppreference.com/w/cpp/memory以获取更详细的说明。