c/c++拷貝構造函數和關鍵字explicit 關鍵字explicit 修飾構造方法的關鍵字,加上了,就告訴編譯器,不可以隱式初始化對象;不加就可以隱式初始化對象; 下麵的代碼是可以正常編譯執行的,但是加了關鍵字explicit,編譯就會錯我,因為Test t = 100;是隱式初始化對象,但是如果 ...
c/c++拷貝構造函數和關鍵字explicit
關鍵字explicit
修飾構造方法的關鍵字,加上了,就告訴編譯器,不可以隱式初始化對象;不加就可以隱式初始化對象;
下麵的代碼是可以正常編譯執行的,但是加了關鍵字explicit,編譯就會錯我,因為Test t = 100;是隱式初始化對象,但是如果加上強制類型轉換後,就不會有錯誤了。
強制類型轉換:Test t = (Test)100;
class Test{
public:
Test(int d):data(d){//explicit
cout << "C:" << this << endl;
}
}
int main(){
Test t = 100;
}
- 拷貝構造函數如果加上了explicit,下麵的語句就無法編譯通過;不加可以。
class Test{
public:
//拷貝構造函數
explicit Test(const Test &t){
data = t.data;
}
int getData(){
return data;
}
private:
int data;
};
void test(Test x){
}
int main(){
Test t2(t1);//調用拷貝構造函數
//Test t3 = t2;//編譯不過
//test(t2);//編譯不過
}
- 觸發拷貝構造函數的4種方式
1,Test t2(t1);//調用拷貝構造函數
2,聲明的同時就賦值Test t3 = t2會調用拷貝構造函數;但是註意下麵這種不會調用拷貝構造函數。
Test t3;
t3 = t2;//會調用=的重載方法
3,方法的參數是對象類型test(t2);
4,方法的返回值是對象類型。原因:對象tmp在方法結束後就被釋放掉了,要返回到函數外,必須要複製tmp.
但是用gdb看了一下在return處並沒有調用拷貝構造函數,所以test方法結束後,tmp也沒有被釋放,調用test方法的t5的記憶體地址和tmp是一樣的。個人猜測:老版本的gcc編譯器可能會在return處調用拷貝構造函數,但是新的編譯器(gcc 4.8.5-20)為了提高效率,避免了一次多餘的拷貝。
void test(Test x){//進入函數的時點會調用拷貝構造函數
int value;
value = x.getData();
Test tmp(value);
return tmp;//return的時點會調用拷貝構造函數
}
Test t5 = test(t1);