之前我們寫過乙個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...