C 的預設建構函式有無參構造和拷貝構造

2021-10-12 07:18:56 字數 2677 閱讀 5900

c++的預設建構函式有無參構造和拷貝構造

一直沒有注意到這個預設的拷貝構造,因為用得少,但是拷貝構造卻是乙個重要的建構函式。

下面給出三個類:

//無任何顯式建構函式

class

a;

//只有乙個顯式的無參建構函式

classb}

;

//只有乙個顯式的拷貝建構函式

classc}

;

這個是主函式:

int

main()

為了安全起見,應手動寫建構函式,如果有必要的話,下為突然來的腦洞,與本文無關

classdd

(const d &d)d(

const d *d)};

intmain()

預設的拷貝建構函式能幹嗎?

下為示例1:

從這個結果看得出來,a1和a2的data資料成員的位址不是相同的,不會牽一髮而動全身

但是如果data是指標的話,如下示例2:

如果使用c++寫資料結構的話,一般常用的資料結構都會用指標,如果使用這種預設的建構函式很容易導致程式異常,所以,正確的食用方式是:

而我昨天(20.12.16)遇到的問題是,乙個類沒給拷貝構造,有給operator=,功能和拷貝一樣,但不巧的是示例是a的乙個物件先拷貝了乙個物件,操作結束後再=原來的物件,這就導致,一開始兩個物件的指標資料成員已經共用同乙個位址了。

關於賦值運算子=

在主程式中:

int

main()

void

operator

=(a &a)

可是執行了相同的源程式後a1和a2的data位址還是相同。

為什麼呢?我想到了:換言之,和預設拷貝建構函式一樣,也就是說:

a a2 = a1;

<=

> a a2

(a1)

;

於是我把自己寫的拷貝建構函式注釋去掉,果然data的位址就不同了

到這裡我們發現,我過載的operator=沒有用到,確實a a2 = a1和過載的operator=沒有關係,卻和拷貝建構函式有關係,這確實是我的知識盲區。

我再次把拷貝建構函式注釋掉,把主函式改為:

int

main()

這樣就ok了,也就是說,要先建立出物件,再執行賦值操作,值得注意的是:

void

operator

=(a &a)

這裡是對指標指向的位址賦值,也就是說,這個data的空間要先開闢好,可以是在類裡面宣告時就new,也可以是在建構函式裡面new,畢竟建構函式的執行一定在operator=前面。

總結:

a a1;

a a2

(a1)

;//呼叫的是拷貝建構函式

a a2 = a1;

//呼叫的是拷貝建構函式

a a3;

a3 = a1;

//呼叫的是operator=

有無參建構函式

都在物件被構造的時候被呼叫,只是在構造物件時根據new物件的引數型別和個數進行選擇對應的構造方法進行呼叫,當沒有引數時呼叫無參構造方法,有引數時呼叫對應的有參構造方法。建構函式的引數一般用來初始化類的資料成員。建構函式的特點及作用 建構函式的命名必須和類名完全相同。建構函式的功能主要用於在類的物件建...

有無參建構函式

都在物件被構造的時候被呼叫,只是在構造物件時根據new物件的引數型別和個數進行選擇對應的構造方法進行呼叫,當沒有引數時呼叫無參構造方法,有引數時呼叫對應的有參構造方法。建構函式的引數一般用來初始化類的資料成員。建構函式的特點及作用 建構函式的命名必須和類名完全相同。建構函式的功能主要用於在類的物件建...

C 關於預設建構函式和無參建構函式

預設建構函式 在不提供任何建構函式的情況下,編譯器給出乙個不帶引數的,不包含 的建構函式。include using namespace std classa intmain 當已經提供了顯式的建構函式,例如 include using namespace std classa int main 此...