[英]Why and when should use a Copy Constructor in C++? Why shallow copy is discouraged?
讓我們說我們創建一個類Student的對象,我們創建兩個實例/對象類Student(即StudentA和StudentB)。 我們使用淺層復制來初始化B的數據成員,如下所示:
學生B =學生A;
然后我們摧毀了StudentB。 我們在這里面臨懸空指針的情況嗎? 為什么以及如何? 請解釋。
我們在這里面臨懸空指針的情況嗎? 為什么以及如何? 請解釋。
這取決於學生的實施。 如果學生看起來像這樣......
class Student
{
public:
char* m_name;
Student(const char* name)
{
m_name = new char[strlen(name)+1];
strcpy(m_name,name);
}
~Student()
{
delete[] m_name;
}
};
...然后出現問題:當你復制一個學生時,你有兩個指向相同m_name數據的指針,當兩個學生實例被刪除時,m_name數據被刪除兩次,這是非法的。 為避免該問題,Student需要一個顯式的復制構造函數,以便復制的Student具有指向不同m_name數據的指針。
或者,如果學生看起來像這樣......
class Student
{
public:
std::string m_name;
Student(const char* name)
: m_name(name)
{
}
};
...然后沒有問題,因為魔術(即顯式復制構造函數)是在std :: string類中實現的。
總之,如果類包含分配和刪除的指針,則需要顯式復制構造函數(或者顯式沒有復制構造函數,但在任何一種情況下,不僅僅是默認構造函數)。
真的不鼓勵淺層復制 - 這是一個知道什么時候合適的問題。
這里的問題是“所有權”之一。 “Student”類是否“擁有”指向的數據,因此負責(在其析構函數中)刪除該數據。
基本上,如果您獲取擁有某些指向數據的對象的淺表副本,然后銷毀原始數據或副本,則刪除指向數據(由析構函數刪除)。 但是你仍然在對象中有一個沒有被破壞的引用 - 一個懸垂的指針。
OTOH,如果對象不擁有指向的數據,析構函數不會刪除指向的數據,並且沒有問題。 雖然你必須確保某些東西擁有指向的數據,否則你會有內存泄漏。
跟蹤指向數據的所有權是非垃圾收集語言(如C ++)的關鍵技能,並且是應用資源分配初始化模式的基礎。
簡單來說: 如果您的類成員變量包含它也擁有的指針。
另一點是成員的指向數據是不可變的。 通過使用引用計數智能指針在實例之間共享它是不可觀察的。 例如,我有一些看起來像的代碼
struct SizeContainer {
// ... stuff ...
private:
boost::shared_ptr<SizeExpression> p;
};
我沒有聲明復制構造函數和復制賦值運算符,因為無論如何都無法更改p
,因此可以跨多個實例共享它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.