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 此...