關於預設構造

2022-05-27 08:39:12 字數 2980 閱讀 2635

看下面這段**:

1

class

foo2;7

8void

foo_bar()

9;

在c++arm中作者說道:「c++建構函式,在它需要時被編譯器產生出來」;

這裡涉及到2個概念:

1. 需要的時候;

2. 編譯器

當然,我們編寫程式時非常希望物件foo擁有乙個建構函式,自動將val和*pnext進行初始化。這和剛才的「需要的時候」是乙個概念嗎?

no~前者是乙個程式上的概念,而後者,則是編譯器上的概念。

什麼時候才能自動建立建構函式呢?——編譯器需要它的時候! 即使真的編譯器需要它的時候,也不會初始化成員值為0。

這裡強調,如果使用者沒有定義構造,那麼編譯器100%會提供乙個預設構造。但這個預設構造是「有用構造(nontrival)」還是「無用構造(trivial)」?看情況而定。

無用構造內部無參,也不會自動初始化,當然這個操作由編譯器完成,只是用來生成物件。

以下我們討論的,都是在某些情況下,編譯器建立了「有用構造」。

以下4種情況,編譯器立功:

1.帶有「預設建構函式」成員物件

如果乙個類沒有建構函式,但內部有乙個物件成員,該成員類有預設構造,那麼這個類的預設構造將會由編譯器合成。

該合成操作只有在建構函式真正需要被呼叫時才發生。

那麼在c++不同的編譯模組中,編譯器如何避免合成出多個預設構造:

1:  

class foo

2:  ;

7:

8:  

class bar

9:

14:

15:  

void foo_bar()

16:

被合成的bar類的預設構造內部有必要**,用來呼叫foo類預設構造來處理成員物件bar::foo,但它並不產生**來初始化bar::str。

是的,將bar::foo初始化是編譯器的責任。因為foo都有自己的預設構造了,還需要我們來多此一舉嗎?但將bar::str初始化則是程式的責任。

1:  inline bar::bar()
2:

但要注意,這個預設構造只是滿足編譯器的需要。

※如果類a內部含有1個或1個以上的成員物件,那麼a的每乙個構造都必須呼叫每乙個成員物件的預設構造

所以,就算你的**是這樣的:

1:  bar::bar()
2:

編譯器也會這麼做:

1:  bar::bar()
2:
當然,如果成員物件很多,那麼就按照宣告次序由編譯器依次新增構造呼叫

2. 帶有「預設建構函式」基類

類似的道理,如果乙個無任何構造的派生類繼承於有預設構造的基類,那麼這個派生類的預設構造由編譯器生成。

1:  

class base

2:
6:
7:  

class a : public base

8:

它將呼叫基類的預設構造來合成自己的預設構造。

偽**或許如下:

1:  a::a()
2:

3. 帶有「乙個虛函式」

1. class宣告或繼承乙個virtual function

2. class派生自乙個繼承串鏈,其中有乙個或更多的virtual base classes

此時,該類也需要自動合成出缺省構造,該操作由編譯器完成。

1:  

class widget

2:
6:
7:  

void flip(const widget &widget) ;

8:
9:  

//假設bell和whistle都派生自widget類

10:  

void foo()

11:

widget/bell/whistle在編譯期間會發生的操作:

1. 乙個virtual function table(vtbl)會在編譯器產生出來,內放class的virtual function位址;

這裡,因為widget &widget使用了引用操作,所以產生了多型。內部使用了widget的vptr和vtbl中的flip()條目,最終指向的物件為bell或whistle。

4. 帶有「乙個虛基類」

虛基類的實現方法在不同編譯器有極大差異。

1:  

class x ;

2:  

class a : public

virtual x ;

3:  

class b : public

virtual x ;

4:  

class c : public a, public b ;

5:
6:  

//無法在編譯時期確定出實際型別

7:  

void foo(const a* pa) ;

8:
9:  main()
10:  ;

關於建構函式的預設構造

拷貝建構函式 是用於當乙個 使用者自定義型別的物件 作為函式引數時,系統預設 的拷貝建構函式 不能達到目地,這時需要用到 使用者自己定義 的拷貝建構函式 通常是 類的私有成員裡有起到重要作用的指標變數 當進行函式引數的 值傳遞 時,系統會呼叫 拷貝建構函式 如果沒有 自定義 拷貝建構函式 則系統會呼...

C 中關於預設建構函式和預設引數

include using namespace std class time time int s,int h 10,int m 52 time int h,int m,int s hour h minute m sec s 過載建構函式,執行時會根據形參的不同,自動匹配呼叫 類的初始化資料成員的另...

關於c 的預設拷貝建構函式

copy constructor inside the c object model 是本非常好的書,特別是幫助對類的構造和析構的理解。下面我要是的乙個就是關於c 預設的拷貝建構函式 一般我們用到它在以下情況 class a a aa default ctor a a aa copy ctor vo...