拷貝構造函數和賦值函數

一、拷貝構造函數:用一個已經有的對象構造一個新的對象。函數

CAconst CA & c )函數的名稱必須和類名稱相一致,它的惟一的一個參數是本類型的一個引用變量,該參數是const 類型,不可變。this

   拷貝構造函數何時被用到?spa

(1)當用一個已初始化過的自定義類型對象去初始化另外一個新構造的對象的時候。3d

(2)一個對象以值傳遞的方式傳入。在調用函數時須要將實參對象完整的傳遞給形參,系統是經過調用拷貝構造函數來實現的,這樣能保證形具備和實參徹底相同的值。指針

(3)一個對象以值傳遞的方式傳出函數體。在函數調用完畢將返回值帶回函數調用處。此時須要將函數中的對象拷貝到一個臨時對象處並傳給該函數的調用處。對象

 拷貝構造函數爲何傳引用而不傳值?blog

若是拷貝構造函數進行值傳遞的話,那麼形參會產生一個新對象,也就是會調用拷貝構造函數,所以會造成一個死循環。遞歸

調用拷貝構造函數須要先建立形參對象,建立形參對象又須要調用拷貝構造函數,無限遞歸確定是不正確的,因此在這裏要用引用而不是值傳遞。內存

 

二、賦值運算符的重載函數:用一個已經有的對象給一個同一類型的對象賦值。(兩個對象都存在)資源

CA & operator = (const  CA & )

返回值的對象爲引用是爲了能夠連續賦值

賦值函數中能夠既可使用引用也可使用值傳遞,不過值傳遞會多生成一個對象,形成資源的浪費。

class A
{
private:
 int a;
 int b;
public:
 A (const A & arg) // 拷貝構造函數  
 {
  a = arg.a;
  b = arg.b;
 }
 A & operator = ( const A & arg) //重載的賦值函數 
 {
  if(this != &arg)// 先判斷下是不是自身賦值
  {
   a = arg.a;
   b = arg.b;
  }
  return *this;
 }
};

當類中含有指針成員時,二者的意義有很大區別

複製構造函數需爲指針變量分配內存空間,並將實參的值拷貝到其中;而賦值操做符它實現的功能僅僅是將‘=’號右邊的值拷貝至左值,在左邊對象內存不足時,

先釋放而後再申請。固然賦值操做符必須檢測是不是自身賦值,如果則直接返回當前對象的引用而不進行賦值操做。

拷貝構造函數分爲兩類:

一類是系統默認提供的拷貝構造函數,只是簡單的把棧裏面的數據進行拷貝,堆上面的內容沒有進行拷貝。
二類是本身定義的拷貝構造函數,可以對堆上面的東西進行深度的拷貝。
 
這裏又要提到深拷貝和淺拷貝的問題。
 
淺拷貝

深拷貝

class Student{private: char *name;public: Student (const Student & arg) {  int length = strlen(arg.name)+1;  this->name = new char[length];   // 深拷貝,先在堆上分配內存,再拷貝內容。  strncpy(this->name,arg.name,length); } Student & operator=( const Student &arg) {  if(this != &arg)  {   delete []name;// 先銷燬以前分配的堆上的內存  }  int length = strlen(arg.name)+1;  this->name = new char[length];// 從新分配,並拷貝。  strncpy(this->name,arg.name,length);  return *this; }};

相關文章
相關標籤/搜索