您好,登錄后才能下訂單哦!
問題:C++中的空類,默認情況下會產生哪些類成員函數?
系統默認的缺省構造函數和拷貝構造函數(復制構造函數)
系統默認提供的析構函數.
系統默認的運算符重載函數(拷貝賦值函數):用于同類對象之間的賦值.
系統默認的取值運算:當對類的對象進行取地址(&)時會被調用.
1.構造函數法和析構函數存在的必要性和作用:
(1).構造函數的必要性和作用(用構造函數確保初始化):
解決同種類型的不同對象的初始化問題.
保證每個對象的數據成員都有合適的初始值。
(2).析構函數的必要性和作用(用析構函數確保清除):
回收內存和資源,通常用于釋放在構造函數或對象生命期內獲取的資源。
當對象超出它的定義范圍時,編譯器自動調用析構函數.
2.構造函數和析構函數的種類:
(1).一個類可以有多個構造函數(即構造函數的重載).
a. 缺省構造函數:不帶任何參數的構造函數.
當編譯器需要創建一個對象而又不知任何細節時,缺省的構造函數就顯得非常重要.在一個構造類型中沒有構造函數時,編譯器會自動創建一個,然而,一旦有其他的構造函數之后就沒有缺省構造函數.
b. 重載的構造函數:帶參數的構造函數.
屬于類成員函數的重載,通過參數的個數,類型和順序形成重載的條件.其中特殊情況是:
如果類中有其他的構造函數的話,系統就不會提供默認的缺省構造函數以構造對象.
如果類中構造函數帶有默認參數的話,防止出現重載二義性而出錯. 類中的構造函數形成重載時,注意防止重載函數中存在隱式類型轉換而出現重載的二義性.
c. 拷貝構造函數(復制構造函數):
分為系統提供默認的復制構造函數(即淺拷貝或者全盤拷貝),以及自定義的復制構造函數(即深拷貝或者部分拷貝).
(2).一個類只有一個析構函數(即析構函數不存在重載),
析構函數也分為系統默認的和自定義的析構函數(完成指定的其他功能).
3.關于拷貝構造函數(復制構造函數)具體知識點:
(1).定義格式:
類名 (類名+&對象)
{
}
特點:無返回值,參數只有且只能是同類對象的引用.
解疑:為什么不允許定義這種形式 A(A copy) 的拷貝構造函數?
這個拷貝構造函數在參數傳遞的過程中又要調用拷貝構造函數本身,而調用拷貝構造函數時又要先進行參數傳遞,參數傳遞又要調用拷貝構造函數。。。。。。于是陷入不停的分配堆棧的無限遞歸中,而每次壓棧過程中又嵌套了壓棧,致使每一次的壓棧都不能完成,因此,編譯器通過不了這種形式的拷貝構造函數。
(2).拷貝構造函數和賦值運算符重載的比較:
不同的地方:
a.拷貝構造函數是在對象被創建并用另一個已經存在的對象來初始化它時調用的;
如string s1 = "Hello World";
string s2 = s1; //等價于string s2(s1);
b.拷貝賦值函數只能把一個對象賦值給另一個已經存在的對象,使得那個已經存在的對象具有和源對象相同的狀態。
如 string s3;
s3 = s1;
相同的地方:
默認的拷貝構造函數和默認的賦值運算符重載均采用“按成員拷貝”默認方式來實現。
以類String的兩個對象a、b為例。假設a.m_data的內容為“Hello”,b.m_data的內容為“world”。現將a賦值給b,默認賦值運算符重載的“按成員拷貝”意味著執行b.m_data=a.m_data。這將造成三個錯誤:
(1)b.m_data原持有的內存沒有被釋放,造成內存泄漏。
(2)b.m_data和a.m_data指向同一塊內存區域,a或b任何一方變動都會影響另一方
(3)在對象被析構時,m_data被delete了兩次。
4.構造函數的初始化列表知識點:
1).初始化列表的構造順序:
初始化列表中個數據成員的構造順序與其聲明的順序一致.而不是按照出現在初始化列表的順序相關.
2.)必須使用初始化列表的情況?
引用(const)成員和reference類型的成員只能被初始化而不能在初始化列表外進行賦值操作.
類的繼承中基類的構造函數必須通過初始化列表來調用(先調用基類構造函數,然后才是自身的構造函數).
類的聚合中聚合類的嵌套對象的構造可以放在其構造函數體內進行賦值而不必一定初始化才行,和普通的成員變量一致.
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。