C++是一種「基於複製」的語言,例如一個容器Entity
的確將副本放在容器中。
複製是用C++在許多地方製作的,所以最好是你的課正確支持它們,或者你完全禁止它們。
您的類包含一個指向其他數據的指針:當您複製該類的一個實例時應該發生什麼?如果複製指針是可以的,那麼很明顯,刪除析構函數中的指向對象是不行的,因爲仍然存在的副本將指向已刪除的對象。
有一個簡單的規則,有助於避免這種錯誤,被稱爲「三個規則」。如果你已經明確地編碼要麼
在類
那麼最有可能,你需要他們三個的。
在這種情況下,您的析構函數不是默認的析構函數(因爲刪除了指向的對象),所以您還需要告訴在複製構造或賦值的情況下該怎麼做。
如果你喜歡這個類是不可複製的,然後只是確保
struct Entity {
Object *o;
Entity(Object *o) : o(o) {
...
}
~Entity() {
delete o;
}
private:
// Taboo... this should just never happen!!!
// Here is a declaration, but no implementation will be written
Entity(const Entity& other); // Copy constructor
Entity& operator=(const Entity&); // Assignment
};
宣佈禁止運營private
將確保用戶代碼永遠不會打電話給他們(這將是一個編譯時錯誤),和只是聲明它們而不提供實現將確保即使類代碼本身也不會錯誤地調用它們(您會得到鏈接時錯誤)。
但是,在這種特定情況下,這會禁止您的代碼將Entity
實例放入容器中(容器內的元素必須被複制)。你可以把Entity
指針放在一個容器中(指針可以被複制,所以std::vector<Entity *>
對於entities
將是合法的),但是你將負責處理對象的正確生命週期(誰應該調用析構函數以及何時應該發生? )。
如果在另一方面,你有一個指針類的內部數據,並且要允許使類的一個實例的一個副本,您可以:
爲了一個共同的方法是使用「引用計數」指針第二溶液,即尖數據之間的數據「知道」多少指針引用它,並只有在此計數達到0時才銷燬。
謝謝。在我眼中非常具有描述性。 – BWG
同意,非常明確和有用的描述一個重要問題。 – john
在C++ 11中,'= delete'比沒有實現的private更好。 (「3的規則」變成「5的規則」)。有很好的智能指針(unique_ptr/shared_ptr)。 – Jarod42