1 C 侯捷老師課程 拷貝複製 拷貝構造 析構

2021-10-16 17:17:49 字數 2359 閱讀 5867

有兩個經典的類:complex(複數)& string 。前者不含指標(內部資料為兩個double值,分別代表實部和虛部),後者含有指標。下面為complex,其中3-5行是complex類的建構函式。這一類不含指標的類不含拷貝構造 & 拷貝複製 &析構函式。

class

complex

complex& operator +=

(const complex&);

//操作符過載,放入成員

double real()

const

;//const 表示這個函式不會對資料進行任何改動

double imag()

const

;//一是增強可讀性,二是可能會安全一些

private

: double re, im;

//1.首先想到實數的主要部分,並將其放置在private

friend complex&

_dopl

(complex*

,const complex&);

};

string類,內部含有乙個指標,以這個指標來指向任意長度的字串資料。其中第四行和complex一樣,是乙個建構函式。其中5-9行是 拷貝構造、拷貝複製、析構函式。後文詳述這三個函式的作用,

class

string

private

: char* m_data;

};

為什麼帶有指標的類就得有拷貝構造呢?string類如下圖,是乙個指標指向乙個陣列資料。

試想這麼一種情況,已有string類 a,string類 b,然後 執行**b = a。我們的目的是想開闢兩片記憶體,只是這兩片區域存放著相同的資料,兩個指標分別指向這兩片區域。但是按照 =操作符的預設執行過程,會按照下圖進行,實際執行結果會變成:b的指標指向a的指標指的區域。這樣不僅達不到我們想要的目的,還會造成問題:1.b的指標最初指向的那片區域還沒收回來,2.b相當於是乙個a的別名,沒達到我們想要的效果。

所以為了達成目的:開闢兩片記憶體,只是這兩片區域存放著相同的資料,兩個指標分別指向這兩片區域。寫出**如下:

inline

string& string:

:operator =

(const string& str)

//拷貝賦值

//檢查是不是在自我賦值,因為自我賦值上來把右邊殺了。。就沒複製的東西了。

//所以這一步是必要的。。不然結果也錯了

delete

m_data;

//把指標指的老值殺了

m_data =

newchar

[strlen

(str.m_data)+1

];//建立新地盤

strcpy

(m_data, str.m_data)

;//給新地盤放上覆制的新值

return

*this

;}

為了實現 a=b

先忽略 if那一行的**。先解釋後面部分,按照三步來進行,先把a的指標指向的那片區域收回來,再按照b指標指向區域內容的長度new 乙個新的char陣列,最後將a指標指向的區域的內容拷貝至b指標指向的char陣列中。

if那一行是為啥呢?因為有這麼一種情況,如果有人 寫** a = a。按照我們的需求,這一行**我們想要他什麼也不做即可。但是按照以上**三步走,第一步就把a指向陣列給釋放了,第二三步完全進行不下去了,和我們的需求大相徑庭。所以為了防止這種情況,我們寫上這一行,如果遇到自我賦值,什麼都不做直接返回即可。

拷貝構造是為了應對這樣一種應用場景:現有string 類 a,執行** string b=string(a)。按照預設的拷貝規則(令兩指標指向同一片區域),一樣會造成記憶體洩漏,達不到想要的目的(原因同拷貝複製)。

inline

string:

:string

(const string& str)

原理同拷貝複製,兩步走而已。

按照上文的分析,發現,存在指標指向別處,導致原本所指區域被放養的現象(此即記憶體洩漏,相當於失去對這片區域的掌控,且這片區域還白白地佔著寶貴的資源)。析構函式會在此類物件被釋放時自動執行,如下的析構函式表示,釋放此物件指標所指的區域。

inline

string ::~

string()

侯捷老師C 基礎課程筆記1 2

基於物件 object based 與物件導向 object oriented 的區別 通常 基於物件 使用物件,但無法利用現有的物件模版產生新的物件型別,繼而產生新的物件。即 基於物件 只有封裝,沒有繼承和多型的特點。物件導向 具有 封裝 繼承 多型 三大特點,缺一不可。版本c 98 是c 1.0...

C 拷貝構造 拷貝複製 析構函式

帶有指標的成員的類必須有拷貝建構函式和拷貝賦值函式,淺拷貝預設的賦值函式會將乙個指標賦值給另乙個,導致進行賦值的物件指標指向的內容記憶體洩漏 string.h ifndef mystring define mystring class string private char m data endif...

C (2) 拷貝構造 拷貝複製 析構

拷貝建構函式,與建構函式不同的是。傳入值的型別是它自己const string str。拷貝賦值函式同理,傳入的是與自己同型別的引數。inline string string const string str 如上 所作的操作為深拷貝 s2 s1 編譯器預設版本只把指標拷貝過來的為淺拷貝 如字串s2...