C ++对象组合,依赖注入和复制构造器

时间:2014-01-29 09:52:41

标签: c++ object destructor copy-constructor composition

我想在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

2 个答案:

答案 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以获取更详细的说明。