c++標準是這樣寫的預設建構函式是由編譯器在需要的時候將其合成出來,這裡
#include#includeusing namespace std;
class a
; int main()
強調的是
需要,而非必需,以程式示例:
這個程式本身沒什麼好講的,能講的就是其彙編**,除錯狀態下進入彙編**如下:
11:
你能找到構造函式呼叫的地方嗎即a::a(),找不到吧,因為壓根就沒有建構函式,這個類就相當於乙個整形變數(儲存上相似,用法上不同),其空間是堆疊ebp+4這裡的4個位元組
將程式注釋中的
//string str;
去掉,再次進入彙編看看,**如下:
10:
int
main()
11:
看看,我們的建構函式出現了吧a:a() ,為什麼會出現呢?
因為類裡面有乙個類叫string,我們跟蹤發現string類定義在include/xstring裡,其形式如下:
typedef
basic_string<
char
, char_traits<
char
>, allocator<
char
> >
string;
這是乙個模板類,屬於stl範疇,不信你看看sgi stl原始碼,在機會再講,繼教跟蹤,你會發現basic_string有一系列的建構函式,如下:
explicit basic_string(const _a& _al = _a())
: allocator(_al)
basic_string(const _myt& _x)
: allocator(_x.allocator)
basic_string(const _myt& _x, size_type _p, size_type _m,
const _a& _al = _a())
: allocator(_al)
basic_string(const _e *_s, size_type _n,
const _a& _al = _a())
: allocator(_al)
basic_string(const _e *_s, const _a& _al = _a())
: allocator(_al)
basic_string(size_type _n, _e _c, const _a& _al = _a())
: allocator(_al)
其實重要的是第乙個建構函式,因為此處呼叫就是它,給basic_string分配乙個記憶體分配管理器
明白了吧,此處有是因為類裡面有乙個string類的物件,別人屬於你,別人有自已的建構函式,需要為其賦乙個初始值,你總不能不讓吧,於是編譯器就合成乙個預設的建構函式,呼叫string裡的建構函式,為string對像置乙個初始狀態
建構函式的確是不一定會有的,而且類裡的一些內建型別預設建構函式也不會給其設定乙個預設值的,不信你再看看彙編,**有對ptr的賦值
有四種情況編譯器會為合成預設建構函式
1:含有預設預設/建構函式的成員類物件
2:帶有預設/建構函式的基類物件
3: 含有虛函式的類
4:繼承虛基類的類
可以參考此書《深入理解c++物件模型》第二章
C 編譯器生成預設建構函式的四種情況
第一種是類成員中有成員是類物件,並且該成員的類含有預設建構函式,那麼c 編譯器會幫你給這個類也生成乙個預設建構函式,用來呼叫其成員物件的建構函式,完成該成員的初始化構造。需要強調的是,如果這個成員的類也沒有給出缺省建構函式,那麼c 編譯器也不會幫你生成該類的預設建構函式。第二種情況是這個類的基類有預...
什麼情況下C 編譯器會生成預設的建構函式
問題 對c 初學者來說存在乙個誤區,如果類沒有定義任何建構函式,編譯器會自動生成預設的建構函式。注意 這種說法是錯誤的。正確的說法 惟有預設建構函式 被需要 的時候編譯器才會合成預設建構函式。那什麼情況下是 被需要 的時候?以下有四種情況編譯器會自動合成預設建構函式 情況1 含有類物件資料成員,該類...
編譯器生成預設建構函式情況
1 類和物件 當乙個a類有預設建構函式,b類中包含a類物件,並且b類沒有建構函式,那麼編譯器會給b類生成預設建構函式 2 繼承 基類有預設的建構函式,派生類沒有顯示給出建構函式。這種情況下,因為建立派生類物件會呼叫基類的建構函式,所以編譯器認為有必要生成派生類建構函式,所以會生成乙個派生類的建構函式...