天天看點

初始化 指派 拷貝

折騰我挺長一段時間,基本挺明白了,先來個差別說明:指派操作是在兩個已經存在的對象間進行的,而初始化是要建立一個新的對象,并且其初值來源于另一個已存在的對象。編譯器會差別這兩種情況,指派的時候調用重載的指派運算符,初始化的時候調用拷貝構造函數。如果類中沒有拷貝構造函數,則編譯器會提供一個預設的。這個預設的拷貝構造函數隻是簡單地複制類中的每個成員。 下面看例子。

c++中初始化和指派操作差别是很大的。

  對于基本資料類型差别不大:

  比如:

  int a = ; // initialization, copy 0X000C to a
  a = ; // assignment, copy 0X000C to a
           

  但是對使用者自定義的資料類型比如String 初始化和指派就差别很大:

class String {
   public:
   String( const char *init ); // intentionally not explicit!
   ~String();
   String( const String &that );
   String &operator =( const String &that );
   String &operator =( const char *str );
   void swap( String &that );
   friend const String // concatenate
   operator +( const String &, const String & );
   friend bool operator <( const String &, const String & );
   //...
   private:
   String( const char *, const char * ); // computational
   char *s_;
  };
           

  初始化的構造過程比較簡單:先配置設定一個足夠大的空間然後填充上資料:

 

 String::String( const char *init ) {
   if( !init ) init = "";
   s_ = new char[ strlen(init)+ ];
   strcpy( s_, init );
  }
           

  析構過程更簡單:

String::~String() { delete [] s_; }
           

  但是如果指派操作就複雜多了:

  String &String::operator =( const char *str ) {
  
   if( !str ) str = "";
  
   char *tmp = strcpy( new char[ strlen(str)+ ], str );  // 多了中間變量
  
   delete [] s_; // 多了删除s_;
   s_ = tmp;   // 多一個指派操作!現在是指向字元的指針,如果是個大對象,效率的差别可想而知.
  
   return *this;
  }
           

  建議在條件允許的情況下最好在初始化的時候就指派,而盡量避免用=号指派了,比如用成員初始化清單來初始化成員資料,不在構造函數裡用指派操作給成員資料.

複制構造函數與指派操作符之間的差別

複制構造函數又稱拷貝構造函數,它與指派操作符間的差別展現在以下幾個方面

1.從概念上區分:

複制構造函數是構造函數,而指派操作符屬于操作符重載範疇,它通常是類的成員函數

2.從原型上來區分:

複制構造函數原型 ClassType(const ClassType &); 無傳回值

指派操作符原型 ClassType& operator=(const ClassType &); 傳回值為 ClassType 的引用,便于連續指派操作

3.從使用的場合來區分:

複制構造函數用于産生對象,它用于以下幾個地方:函數參數為類的值類型時、函數傳回值為類類型時以及初始化語句,例如(示例了初始化語句,函數參數與函數傳回值為類的值類型時較簡單,這裡沒給出示例)

ClassType a;         //
ClassType b(a);     //調用複制構造函數
ClassType c = a;    //調用複制構造函數
           

而指派操作符要求‘=’的左右對象均已存在,它的作用就是把‘=’右邊的對象的值賦給左邊的對象

ClassType e;
Class Type f;
f = e;              //調用指派操作符
           

4.當類中含有指針成員時,兩者的意義有很大差別

複制構造函數需為指針變量配置設定記憶體空間,并将實參的值拷貝到其中;而指派操作符它實作的功能僅僅是将‘=’号右邊的值拷貝至左值,在左邊對象記憶體不足時,先釋放然後再申請。當然指派操作符必須檢測是否是自身指派,若是則直接傳回目前對象的引用而不進行指派操作