關於c++ default constructor的問題,這個說法對嗎?
真的沒有一個是真的嗎?在c++ 11標準里,仍然是這樣嗎?例如一個class裡面只有非class 的member object也不繼承,這樣的話就不存在default constructor?我怎麼記得不論如何,default constructor都會生成?@阿帥哥 的答案是正確的。即便一個{}的構造函數也不會被構造。。
只要有copy constructor,default constructor就不會被合成,所以第一條是錯的。第二條更不用說了,你放個指針的話初始值不一定是nullptr。
其實最好的辦法還是RTFM……
1.
如果你不定義任何constructor,那麼default constructor是會有的,編譯器自動給你生成一個空的。如果你定義了其他constructor,但沒有定義default constructor,編譯器也不會再給你生成空的default constructor。C++11的變化是,這種情況下如果你還想要編譯器給你生成那個空的default constructor,可以用新的=default語法,寫起來更簡便。如果你明確不想要這個constructor,可以用=delete明確禁用,方便編譯器也方便人讀。也就是說C++11隻是給了你一點語法糖,規則、語義都沒有變化。2.
C++自動生成的那個空的default constructor只會保證基類的default constructor以及那些class member的default constructor會被調用,其他什麼都不會做。如果你有int,char*這樣的基礎類型,default constructor不會給他們初始化值。3.
一個類完全可以沒有default constructor,雖然這會給類的用途上帶來限制,但這是語法所允許的。C++11沒仔細研究過,按之前的標準當你一個constructor都沒有定義的時候,會有default constructor,沒有參數;當你至少定義了一個的時候就沒有了。default constructor會調用member的默認構造函數,實際上任何構造函數都會,只要這個member沒有出現在初始化列表裡;但是對int這樣的類型來說,默認構造函數不代表這個欄位會被初始化——它們實際上什麼都不幹,所以欄位的值仍然是沒有初始化的狀態。可以在初始化列表裡明確指定各個member構造函數的欄位,如果不指定,就會使用member的默認構造函數。如果某個member沒有默認構造函數,還會報編譯錯誤,這種情況下就必須在初始化列表當中顯示指定。
第一個,「任何」不對,有的類沒法生成默認ctor,比如有引用成員的類第二個,原生類型是不會初始化的
是那本深入理解c++模型嗎?我的理解是,編譯器是否合成default constructor要看是否有必要,這部分內容著重強調虛擬和繼承機制。如果class存在虛函數,父類或者class member,編譯器必須有一個constructor的動作,否則如果是非常簡單的class,只要分配內存就可以了。初學者,如理解有誤,還請指正
建議看看深度理解C++對象模型這本書,裡面有專門的章節說這兩個問題。1.第一個問題編譯器不會為有自定義構造函數的class生成default ctor,即使在生成的ctor中也分trival和nontrival。2.第二個問題,其實可以自己寫個測試類試試啊,編譯器不會幫你把pointer賦值NULL,int賦值0如有疏漏歡迎指教。
第1條:如果一個類存在任何構造函數都將不再有自動生成的默認構造函數。
C++11的主要不同在於,可以通過= default和= delete強制生成或刪除默認構造函數。第2條:自動生成的默認構造函數會調用基類(如果有)的默認構造函數,(若該對象非靜態非全局)並對所有數據成員進行默認初始化。默認初始化區別於值初始化,對於基本類型數據成員將初始化為garbage value,對於類類型數據成員則將執行其默認構造函數。
C++11的主要不同在於,對於存在類內初始化的,自動生成的默認構造函數將會依據類內初始值初始化。以上。(等我回寢室核查一下以上的說法,如有錯誤,望見諒)考慮這樣一段代碼:
#include &
using namespace std;
class A
{
private:
int num;
public:
int Num() const { return num; }
void Num(int val) { num = val; }
};
class B : public A
{
};
class C
{
private:
int num;
public:
int Num() const { return num; }
void Num(int val) { num = val; }
virtual void Fuck()
{
}
};
A a;
a.Num(1);
cout &<&< a.Num() &<&< endl;
編譯後,用IDA查看編譯後的代碼 (VC++2015 DEBUG)
可以看到此處並沒有調用c++所謂的默認構造,那到底生成了沒有呢?在IDA里搜索A::A字元串,你會發現Pattern is not found
那是不是我搞錯了呢? 你再搜索A::Num是有的可以精準定位,所以.確實沒有默認構造.
看下一個例子B b;
b.Num(2);
cout &<&< b.Num() &<&< endl;
代碼中,B只繼承了A,在IDA里搜索A::A或者B::B字元串,仍然是Pattern is not found , 另外反彙編代碼如下:
C c;
c.Num(3);
cout &<&< c.Num() &<&< endl;
反彙編代碼:
C類同樣沒有寫構造函數,但是你會發現他卻調用了一個無參構造,這說明這時候確實有了?為什麼有了?他幹了什麼?進到C::C();里看下....class D : public C
{
private:
int num;
public:
int Num() const { return num; }
void Num(int val) { num = val; }
virtual void Fuck()
{
num = 2;
}
};
反彙編:
default constructor 只有在必須的時候才被填充
送樓主一句話,看書不認真,也不動手寫代碼驗證
effctive c++第七條?
使用初始化列表為啥效率高,不就是因為只調用一次copy,而不是多調用一次構造函數么。
我的回答居然在輪子哥上邊。推薦閱讀:
※c++中的左值跟右值怎麼區分?
※語句str2= str1 + (str1.size() - 1," ")為什麼只有1個空格添加進去了?
※C++中類B需要訪問類A的私有成員變數,除了將B聲明為A的友元類外還有其它方法嗎?
※如何在#define里使用"#"?
※繼承模板類為什麼可以用this訪問基類?