淺拷貝與深拷貝

2021-09-17 18:13:04 字數 1498 閱讀 9907

之前我們寫過乙個string類的基本封裝,現在我們看下面的這個例子:

#includeclass string

~string() }

private:

char *_pstr;

};int main()

編譯雖然會通過,但是一旦執行就會報錯。原因是因為當類裡面有指標物件時,拷貝構造和運算子過載只進行值拷貝,兩個物件共用同一塊空間,物件銷毀時程式會發生記憶體訪問違規。str2需要呼叫string類的拷貝建構函式來建立,由於未顯示定義,因此使用預設的拷貝建構函式。兩個例項指向同乙個位址,第乙個物件銷毀時,那麼第二個例項就無法訪問到對應記憶體。

淺拷貝也稱為位拷貝,編譯器只是將物件中的值採用基本型別值賦值的方式拷貝過來,如果物件中管理資源,最後就會導致多個物件共享同乙份資源,當乙個物件銷毀時就會將該資源釋放掉,而此時另一些物件不知道該資源已經被釋放,繼續對資源進行操作的時候,就會發生訪問違規。那麼如何解決呢?

string(const string& s)

:_str(new char[strlen(s._str) + 1])

我們可以看到上面的拷貝建構函式new了一塊新的記憶體空間,因此str1和str2雖然內容相同,但是他們位址不同,深拷貝的意思其實也就是將位址也進行拷貝,不同的例項分別開闢不同的記憶體空間,這樣一旦某乙個例項銷毀後,便不會發生記憶體的違規訪問了。

class string

_str = new char[strlen(str) + 1];

strcpy(_str, str);

} string(const string& s)

:_str(new char[strlen(s._str) + 1])

void print()

string& operator=(const string& s)

return *this;

} friend ostream& operator<<(ostream& _cout, const string& s)

~string() }

private:

char *_str;

};void teststring()

int main()

class string

string(const string& str)

:_str(null)

//借助建構函式

/*string& operator=(const string& str)

return *this;

}*///借助拷貝建構函式

/*string& operator=(string str)

*/ ~string() }

const char* c_str()

private:

char * _str;

};

圖示挖個坑o(╥﹏╥)o

「淺拷貝」與「深拷貝」

c 中物件的複製就如同 轉殖 用乙個已有的物件快速地複製出多個完全相同的物件。一般而言,以下三種情況都會使用到物件的複製 1 建立乙個新物件,並用另乙個同類的已有物件對新物件進行初始化,例如 cpp view plain copy class rect rect rect1 rect rect2 r...

淺拷貝與深拷貝

淺拷貝 1 2 myclass a,b a b 為了封裝性和解耦,同型別的兩個物件之間進行賦值操作時,所有成員變數被複製,包括私有成員 指標變數。類的成員函式在傳遞或返回物件時都會進行物件複製產生臨時物件,比如函式呼叫時實參變為形參,以及函式返回物件。考慮到效能和使用者要求不同,編譯器不複製物件內部...

「淺拷貝」與「深拷貝」

c 中物件的複製就如同 轉殖 用乙個已有的物件快速地複製出多個完全相同的物件。一般而言,以下三種情況都會使用到物件的複製 1 建立乙個新物件,並用另乙個同類的已有物件對新物件進行初始化,例如 cpp view plain copy class rect rect rect1 rect rect2 r...