類的預設成員函式上(構造 析構和拷貝建構函式)

2021-09-02 08:17:15 字數 3915 閱讀 8232

1.建構函式

2.析構函式

3.拷貝建構函式

4. 賦值操作符過載

5. 預設拷貝構造與賦值運算子過載的問題

6. const成員函式

7. 取位址及const取位址操作符過載

在乙個空類中如果什麼成員都沒有,依然會有6個預設的成員函式

建構函式是乙個特殊的成員函式,名字與類名相同,建立類型別物件時由編譯器自動呼叫,保證每個資料成員 都有 乙個合適的初始值,並且在物件的生命週期內只呼叫一次。

建構函式的特點

1.函式名與類名相同。

2.無返回值。

3.構造物件的時候系統會自動呼叫建構函式。

4.可以過載。

5.可以在類中定義,也可以在類外定義。

6.如果類中沒有給出建構函式,編譯器會自動產生乙個預設的建構函式,如果類中有建構函式,編譯器就不會產生預設建構函式。

7.全預設的建構函式和無參的建構函式只能有乙個,否則呼叫的時候就會產生衝突。

8.沒有this指標。因為建構函式才是建立物件的,沒有建立物件就不會有物件的首位址。

//給出乙個日期類

class date

date(int year = 1900, int month = 1, int day = 1)//全預設的建構函式

//注意無參構造和全預設的構造智慧型有乙個,否則呼叫時會出現混亂

date(int year, int month, int day)//帶引數構造

void my_printf()

private:

int _year; // 年

int _month; // 月

int _day; // 日

};void test()

int main()

析構函式函式名是在類名加上字元~。

無引數無返回值(但有this指標)

乙個類有且只有乙個析構函式,所以肯定不能過載。若未顯示定義,系統會自動生成 預設的析構函式

物件生命週期結束時,c++編譯系統系統自動呼叫析構函式。

注意析構函式體內並不是刪除物件,而是做一些清理工作。(比如我們在建構函式中動態開闢過一段空間,函式結束後需要釋放,而系統自動生成的析構函式才不管記憶體釋放呢,所以需要人為地寫出析構函式)

注意:物件生命週期結束後,後構造的物件先釋放。

typedef int datatype;

class seqlist

~seqlist()

} private:

datatype* _pdata;

size_t _size;

size_t _capacity;

};int main()

//當涉及系統資源的時候析構最好自己給出

首先對於普通型別的物件來說,它們之間的複製是很簡單的, 而類物件與普通物件不同,類物件內部結構一般較為複雜,存在各種成員變數。

下面看乙個類物件拷貝的簡單例子。

#includeusing namespace std;

class cexample

//拷貝建構函式

cexample(const cexample & c)

//析構函式

~cexample()

void show() };

int main()

上面這段**就是將建立的物件a複製給b,對於相同型別的物件我們可以使用拷貝建構函式來進行複製cexample(const cexample & c)就是我們實現的拷貝建構函式

拷貝建構函式的特點

拷貝建構函式是建構函式的乙個過載形式,也是一種特殊的建構函式,因此函式名就必須和類名相同。

拷貝建構函式的引數只有乙個且必須使用引用傳參,使用傳值方式會引發無窮遞迴呼叫

若未顯示定義,系統生成預設的拷貝建構函式。 預設的拷貝建構函式物件按記憶體儲存按位元組序完成拷 貝,這種拷貝我們叫做淺拷貝,或者值拷貝,既然系統會預設生成,那麼我們就不需要自己去實現呢?當然不是。後面我們會對於深淺拷貝做詳細的解釋。

拷貝建構函式的呼叫時機

1.當類物件作為引數進行函式傳參時呼叫

void fun(cexample c )
2.當類物件作為函式的返回值的時候

cexample fun()

3.當對類物件進行初始化的時候

cexample a(100);

cexample b=a;

關於深淺拷貝

所謂淺拷貝,指的是在物件複製時,只對物件中的資料成員進行簡單的賦值,預設拷貝建構函式執行的也是淺拷貝。大多情況下「淺拷貝」已經能很好地工作了,但是一旦物件存在了動態成員,那麼淺拷貝就會出問題了,讓我們考慮如下一段**:

#include#includeusing namespace std;

class rect

~rect()

private:

int width;

int height;

int *p;

};int main()

上面的**在執行時會出現錯誤,當使用預設拷貝函式(淺拷貝)對物件進行複製時出現錯誤。當建立r1時系統在堆上分配了空間,當使用r1複製r2時只是將p的值複製的過去,也就是兩個p指向了同一塊堆空間,在析構函式呼叫時就會對同一塊空間釋放兩次,這就是錯誤原因。我們要的不是兩個p有相同的值,而是兩個p所指向的空間有相同的值

深拷貝

直接上**

#include#includeusing namespace std;

class rect

rect(const rect &r)

~rect()

private:

int width;

int height;

int *p;

};int main()

上述**就是乙個深拷貝的**,所謂深拷貝不僅僅時進行簡單的複製,而時重新動態分配空間,此時r1,r2分別指向不同的位址空間。

拷貝建構函式小結

兩種拷貝方式:深、淺拷貝

當我們再對類物件進行等號賦值時,會呼叫拷貝建構函式,如果我們沒有顯示定義的情況下,系統會預設生成拷貝建構函式–淺拷貝。當類成員僅僅只有值拷貝時,系統生成的拷貝建構函式都可以完成拷貝,但是當類的成員有指標時,若採用淺拷貝,在拷貝時兩個指標就會指向同一塊位址空間,當物件快結束時,體統會呼叫兩次析構函式,將指標所指的空間釋放兩次,就會出現錯誤。這時就必須採用深拷貝。

深拷貝和淺拷貝的區別就在於深拷貝會在對上新申請空間來儲存資料。這樣就不會對記憶體進行二次釋放。

拷貝建構函式的作用

作用就是進行物件的複製,用乙個物件的例項對該物件的另乙個是例進行初始化

c++建構函式以及析構函式的若干面試問題

q1:建構函式能否過載,析構函式能否過載,為什麼?

a1:建構函式可以,析構函式不可以。

q2:析構函式為什麼一般情況下要宣告為虛函式?

a2:虛函式是實現多型的基礎,當我們通過基類的指標是析構子類物件時候,如果不定義成虛函式,那只呼叫基類的析構函式,子類的析構函式將不會被呼叫。如 果定義為虛函式,則子類父類的析構函式都會被呼叫。

q3:什麼情況下必須定義拷貝建構函式?

a3:當類的物件用於函式值傳遞時(值引數,返回類物件),拷貝建構函式會被呼叫。如果物件複製並非簡單的值拷貝,那就必須定義拷貝建構函式。例如大的堆 棧資料拷貝。如果定義了拷貝建構函式,那也必須過載賦值操作符。

類的預設成員函式

class time time int hour,int minute,int second 有參的建構函式 time int hour 9,int minute 54,int second 23 全預設建構函式 time int hour,int minute 12,int second 30 半...

類和物件(預設成員函式)

建構函式不是開空間建立物件,而是初始化物件,更嚴謹的說是賦初值 特性初始化列表 class date private int year int month int day explicit 析構函式不是完成對物件的銷毀,區域性物件銷毀由編譯器完成,而在物件銷毀時會呼叫析構函式,完成類的一些資源清理工...

c 類的預設成員函式

類的組成包括資料成員與成員函式。在類中一共有有六個預設成員函式,建構函式 拷貝建構函式 析構函式 賦值操作符過載 取位址操作符過載 const修飾的取位址操作符過載 利用乙個例項 日期類 進行舉例 先是定義乙個日期類 class date 這就是乙個簡單的類定義。下面依次介紹各個預設成員函式 一.建...