c/c++拷貝構造函數和關鍵字explicit


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,下面的語句就無法編譯通過;不加可以。
#include <iostream>
using namespace std;
class Test{
public:
  Test(){}
  //拷貝構造函數
  explicit Test(const Test &t){
    cout << "in copy" << endl;
    data = t.data;
  }
  int getData(){
    return data;
  }
private:
  int data;
};
void test(Test x){

}
int main(){
  Test t1;
  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);

一個注意點,拷貝構造函數的參數最好用const限定,不然下面的代碼編譯不過(gcc 4.8.5-20)

#include <iostream>
using namespace std;

class Test{
public:
  Test(int d = 0):data(d){
    cout << "C:" << d << " " << this << endl;
  }
  Test(Test &t){
    cout << "Copy:" << t.data << " " << this << endl;
    data = t.data;
  }

  Test& operator = (const Test &t){
    cout << "Assign:" << this << " = " << &t << endl;
    if(this != &t){
      data = t.data;
    }
    return *this;
    }
  ~Test(){
    cout << "F:" << this->data << "->" << this << endl;
  }
  int getData()const{
    return data;
  }
private:
  int data;
};


Test fun(Test &x){
  int value = x.getData();
  Test tmp(value);
  return tmp;

}

int main(){
  Test t1(100); 
  //編譯不過,因為拷貝構造函數的參數沒有用const限制
  Test t2 = fun(t1);

  return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM