第十二章 預設複製建構函式和賦值運算子

2021-07-03 21:03:17 字數 2152 閱讀 9885

比如string str2 = str1;其中str2為已經生成的物件。這個時候,編譯器會把str1中的成員按值賦給str2中的每個成員。

如果物件成員中沒有使用new來分配動態記憶體空間,則編譯器自動生成的預設賦值函式,就可以正確實現,而不會出現錯誤。

但是如果物件成員中有new分配的動態記憶體空間,比如下面的這個類,str2中的指標str和str1中的指標str會指向同乙個記憶體空間。

當str2執行析構函式時,釋放了記憶體空間。這個時候也就是說str1的str指向的記憶體空間被釋放了。所以就會出現錯誤。

這個情況還有三種方式也會:

string str2(str1);

string str2 = string(str1);

string *pstr = new string(str1);

比如void callmey(string str2); callmey(str1);//這個時候會產生乙個臨時物件,將str1中的成員按值賦給臨時物件的成員。和上面

的情況一樣,都會出現錯誤。

應該定義預設複製建構函式為:(實現深度複製)

//複製建構函式

stringbad::stringbad(const stringbad &s)

當用乙個已經生成的物件,給另外乙個已經生成的物件賦值時,會呼叫賦值運算子。複製的時候和呼叫複製建構函式一樣,都是成員按值賦值。

如果涉及到new動態分配記憶體空間,就會出現錯誤。

比如:string str1("yxk");

string str2;

str2 = str1;//這個時候會呼叫賦值運算子函式,將str1中各個成員按值賦給str2中的各個成員。如果也涉及到new分配的動態記憶體時,也會出現錯誤。

string str3("xiaokui");

str3 = str1;//將str1中的值賦給str3中的值。這個因為存在new分配的動態記憶體,所以在賦值運算子函式中應該首先釋放str3中存在的動態記憶體空間,

再分配記憶體,將str1中的str指向的記憶體空間內容複製過來。也正是因為先釋放自身的記憶體空間,所以不能將物件自身賦值給自身。

應該定義賦值運算子為:(實現深度複製)

//賦值運算子

stringbad & stringbad::operator=(const stringbad & st)

下面是c++ primer plus 第十二章的第乙個例子:

#include #ifndef stringbad_h_

#define stringbad_h_

class stringbad

;#endif

#include #include "stringbad.h"

using namespace std;

int stringbad::num_strings = 0;

stringbad::stringbad(const char *s)

stringbad::stringbad()

stringbad::~stringbad()

std::ostream & operator<

//複製建構函式

stringbad::stringbad(const stringbad &s)

//賦值運算子

第十二章 檔案

文字檔案 文字檔案是一種由若干字元構成的檔案,可以用文字編輯器進行閱讀或編輯。以txt py html等為字尾的檔案都是文字檔案。2.二進位制檔案 二進位制檔案一般是指不能用文字編輯器閱讀或編輯的檔案。以 mp4 png等為字尾的檔案都是二進位制檔案,如果想要開啟或修改這些檔案,必須通過特定軟體進行...

第十二章 dp

動態規劃策略 將原始問題拆分為多個子問題,將子問題結果記錄,方便復用子問題的解 遞迴 記憶化 遞推 是動態規劃的一體兩面,本質都是一樣的 遞推減少了呼叫次數,空間上還能優化,一般選擇遞推方式 遞迴 記憶化 int memo maxn 將o 2 n o n intfibonacci int n 遞推 ...

第十二章 異常

一 異常的概念 錯誤 編譯器 異常 執行期,程式沒有正常按照期望執行 異常產生時,在對應位置產生異常型別物件,程式 暫停 如果上下文有異常處理程式,對應處理 沒有則 異常向上傳播 報錯退出 異常向上傳播 如果異常在函式中產生,會傳播給函式的呼叫者 如果異常在模組的頂級位置,會傳播給引用該模組的模組 ...