我對C 相當陌生,正在進行一個個人專案。我想在C 中創建一個vector<Entity*>entitities,每個Entity物件都是唯一的。我在頭檔案Entity.h里面有一個我想創建的類。現在,Entity需要兩個成員變數:
Rectangle rect - 一個Rectangle型別的物件,它有四個浮動變數作為成員變數(x1, y1, x2, y2),它們是一個矩形的兩個對角的坐標vector<Component*> - 基類Component的一些不同的組件,以及一些派生類。Class Component的代碼是這樣的:/*************************** BASE CLASS **************************/
class Component
{
public:
virtual ~Component() = default;
virtual Component* Clone()= 0;
};
/*************************** DERIVED CLASS 1 **************************/>
class BasicComponent。public Component
{
private:
int B= 0;
public:
BasicComponent* Clone() override{
return new BasicComponent(B)。
}
BasicComponent(const int& mB) :B(mB){}.
BasicComponent() :B(0) {}.
};
/*************************** DERIVED CLASS 2 **************************/
class AdvancedComponent。public Component
{
private:
float A = 0.f;
int iA = 0;
public:
AdvancedComponent* Clone() override{
return new AdvancedComponent(A,iA)。
}
AdvancedComponent(const float& mA, const int& miA) : A(mA),iA(miA){}。
AdvancedComponent() :A(0.f),iA(0) {}.
};
由于我希望物體向量中的每個Entity都是唯一的,也就是說,有它自己的矩形和組件,我應該如何創建這個類?
我的問題是,class Entity應該是什么樣子的?我是否應該為這個類創建單獨的CopyConstructor、Assignment Constructor和Destructor?另外,如果我想實作將一個物體復制到另一個物體中(深度復制),是否有必要擁有全部三個(復制、賦值和破壞器)?
uj5u.com熱心網友回復:
我的問題是,Entity類應該是什么樣子?我是否應該為這個類創建單獨的CopyConstructor、Assignment Constructor和Destructor?另外,如果我想實作將一個物體復制到另一個物體中(深度復制),是否有必要擁有全部三個(Copy、Assignment和Destructor)?
這個問題的答案其實并不取決于 Entity 的外觀,而是取決于它的語意是什么。
你說每個 Entity 都是 "唯一的",但是 C 中的每個物件(甚至每個 int,即使它們碰巧具有相同的值)在技術上是唯一的。那么你真正的意思是什么呢?
一個Entity是否應該是可復制的?復制構建一個 Entity 將意味著兩個 Entity 物件具有相同的內容(如果組件指標是淺層復制的,那么從邏輯上講,如果它們是深層復制的)。
如果不是這樣,你可能不想寫一個(或者可能明確地洗掉)復制建構式和/或復制分配運算子。
一個物體是否應該是可移動的?可能是的,因為它不違反唯一性,并且使它們更容易被有效使用。
如果是這樣,你應該確保它有一個移動建構式和移動分配運算子(可以通過撰寫它或者安排編譯器生成有用的默認值)。
另外,如果我想實作將一個物體復制到另一個物體(深度復制)
這似乎違反了你的唯一性約束,但是是的,你需要一個復制建構式和復制賦值運算子來實作。
然而,最佳做法是避免將資源管理與你的程式邏輯交織在一起。因此,與其撰寫所有這些,不如考慮讓一個智能指標為您自動完成。請參閱本答案中提到的零規則進行比較。
事實上,我們可以用很少的代碼來說明所有合理的語意:
我們可以用很少的代碼來說明所有合理的語意。
template <typename ComponentPtr>。 struct ZeroEntity >。 { 矩形的邊界。 std::vector<ComponentPtr> components。 }; 使用 ShallowCopyZeroEntity = ZeroEntity<std::shared_ptr<Component> >。 using NoCopyOnlyMoveEntity = ZeroEntity<std::unique_ptr<Component>> 。 using DeepCopyZeroEntity = ZeroEntity<my::clone_ptr<Component>>。除此之外,我們仍然需要寫一個深拷貝的
的東西clone_ptr,類似于namespace my { template <typename T> class clone_ptr { std::unique_ptr<T> p_; std:: unique_ptr<T> clone() const { return std::unique_ptr<T> {p_ ? p_->Clone() : nullptr}; } public: using pointer = typename std::unique_ptr<T> ::pointer。 explicit clone_ptr(pointer p) : p_(p) {} //復制行為是發生克隆的地方。 clone_ptr(clone_ptr const& other) : p_(other.clone() ) {} clone_ptr& operator=(clone_ptr const& other) { clone_ptr tmp(其他)。 tmp.swap(*this)。 } //由unique_ptr產生的移動行為(和析構器)。 clone_ptr(clone_ptr& & other) = default; clone_ptr& operator=(clone_ptr& &) = default; //現在把所有相同的交換、釋放、重置、操作者*等寫成std::unique_ptr。 }; }......如果這看起來很多,那么想象一下,它將與你的
Entity代碼交錯在一起,而不是像這樣收集到一個地方,是多么的混亂。uj5u.com熱心網友回復:
主要目的只是為了實作對物體的復制。這是否可行?
#include "Components.h"/span> #include "Rectangle.h" #include <vector> using namespace std; class Entity { public: 矩形& 盒子。 向量<組件*>&組件。 //Default constructor call。 Entity()。Box(*new Rectangle), Components(*new vector< Component*> ){}。 //帶引數的構造器呼叫。 Entity(Rectangle& B, vector<Component*>& C) : Box(B), Components(C){}。 //Copy建構式,使物體可復制。 Entity(const Entity& E) : Box(*new Rectangle(E. Box) Box), Components(*new vector< Component*>(E.Components.size()) { for (unsigned int i = 0; i < E.Components.size(); i ) { Components[i] = E.Components[i]->Clone()。 } } /Assignment operator constructor Entity& operator=(const Entity& E){ /Entity* pE = & E; if (this !=&E) { delete& Box; delete& Components; Box = *new Rectangle(E.Box)。 Components = *new vector<Component*>(E.Components.size()) 。 for (unsigned int i = 0; i < E.Components.size(); i ) { Components[i] = E.Components[i]->Clone()。 } } return *this。 } };轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/329398.html
標籤:
