Композиция объектов C ++, конструкторы внедрения и копирования

0

Я хочу создать класс в C++ под названием Entity. Этот объект имеет указатель на элемент Vector3D, который является позицией объекта в трехмерном пространстве. Конструктор позволяет передать указатель типа Vector3D в конструктор, так что экземпляр Vector3D создается вне класса.

Поскольку есть указатель на динамически выделенный объект, конструктор копирования и оператор присваивания должны быть перегружены для глубокой копии вектора. Однако, поскольку вектор может быть передан в конструкторе, он также может использоваться в другом месте и поэтому не может быть удален в деструкторе. Но если новый Entity, созданный через конструктор копирования или назначенный с помощью оператора =, класс сущности должен удалить экземпляр вектора, потому что он был создан в классе 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
    «Поскольку имеется указатель на динамически размещенный объект, конструктор копирования и оператор присваивания должны быть перегружены для глубокого копирования вектора.» Почему они должны? Мне кажется, что Entity не является владельцем Vector3D . Если он владеет Vector3D, то он должен иметь свою собственную копию.
Теги:
object
copy-constructor
composition
destructor

2 ответа

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

Это прекрасный пример того, где использовать новые интеллектуальные указатели С++ 11. Если предполагается, что клиентский код передает права собственности на Entity и может использовать его дольше, чем срок службы Entity, вы используете std::shared_ptr.

Если вы явно хотите передать право собственности на Entity, то клиентский код больше не должен использовать вектор после его переноса в Entity, вы используете std::unique_ptr.

Если клиентский код должен оставаться единственным владельцем и, таким образом, решить, когда вектор будет удален, вы используете std::weak_ptr.

См., Например, http://en.cppreference.com/w/cpp/memory для более подробного описания их.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню