问题
I want to design a class in C++ called Entity. That entity has a pointer to a member of Vector3D which is the position of the entity in 3D space. The constructor allows a pointer of type Vector3D to be passed to the constructor, such that the Vector3D instance is instantiated outside of the class.
Because there is a pointer to a dynamically allocated object, the copy constructor and assignment operator must be overloaded to deep copy the vector. However, because the vector can be passed in the constructor, it may also be used elsewhere and so cannot be deleted in the destructor. But if a new Entity created through the copy constructor or assigned with the = operator, the entity class must delete the instance of vector because it was instantiated within the Entity class.
What is the best way to solve such problems?
#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
回答1:
The best way is to not use a pointer to a Vector3D
, but take it by value. If Vector3D
is what I suspect (a wrapper around 3 floats or integers), there is not much benefit performance wise to sharing it.
You can also start to reason more about ownership and but the burden of destroying the Vector3D
on the client code (the code that constructs an Entity
).
If this is not an option, you can use a 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_;
};
回答2:
This is a perfect example of where to use thew new C++11 smart pointers. If client code is assumed to share ownership with Entity
, and may use it longer than the lifetime of Entity
, you use a std::shared_ptr
.
If you explicitly want to transfer ownership to Entity
, i.e. the client code should not use the vector anymore after wrapping it into an Entity
, you use a std::unique_ptr
.
If the client code should remain the sole owner, and thus decide when the vector gets deleted, you use a std::weak_ptr
.
See for instance http://en.cppreference.com/w/cpp/memory for a more detailed description of them.
来源:https://stackoverflow.com/questions/21427434/c-object-composition-depdendency-injection-and-copy-constructors