天天看點

複制構造函數(拷貝構造函數)在什麼情況下被調用

什麼是複制構造函數:

        複制構造函數是一種特殊的構造函數,具有一般構造函數的所有特性 ,它的形參是本類的對象的引用,比如(類名   對象名)。它的作用是使用一個已經存在的對象(此對象由複制構造函數的參數決定),去初始化同類的一個新對象。那麼複制構造函數一般在什麼情況下被調用呢,有三種情況:

(1)當用類的一個對象去初始化該類的另一個對象的時候

例:   int  main()

          {

                    Point  a(1,2);              // 調用類的構造函數(Point類)

                    Point  b(a);                 // 用已存在的對象a初始化新對象b,複制構造函數被調用

                    Point c=a;                  // 用已存在的對象a初始化新對象c,複制構造函數被調用

                    return 0;

           }

(2)如果函數的形參是類的對象,調用此函數的時候,進行形參和實參相結合時,複制構造函數被調用

例:    void f(Point  p)

         {

               cout<<p.getX()<<endl;

         }

         int main()

         {

                Point  a(1,2);

                f(a);                                         // 函數的形參為類的對象,當調用函數時,實參與形參結合,複制構造函數被調用

                return 0;

          }

                注意:隻有把對象用值傳遞的時候,才會調用複制構造函數,如果傳遞引用,則不會調用複制構造函數。

(3)如果函數的傳回值是類的一個對象,函數執行完成傳回調用者時,複制構造函數被調用

例:         Point  g()

             {

                       Point  a(1,2);

                       return a;                            // 函數的傳回值是類的對象a,傳回函數值時,複制構造函數被調用

             }

            int main()

            {

                       Point  b;

                       b=g();

                       return  0;

             }

              注意:這種情況下,表面上函數g将a傳回給了主函數,但是a是g()的局部對象,離開建立他的函數g以後a就不存在了,不可能在傳回給主函數後繼續生存,是以在處理這種情況的時候編譯器系統會在主函數中建立一個無名的臨時對象,該臨時對象的生存期隻在函數調用所處的表達式中,也就是表達式 b=g() 中。執行語句“ return a ”時,實際上是調用複制構造将a的值複制到臨時對象中,是以在此調用了複制構造函數。函數g運作結束時對象a消失,但臨時對象會存在于表達式“ b=g()”中。計算完這個表達式後,臨時對象的任務也就完成了,改臨時對象就會自動消失。

        以上便是複制構造函數經常被調用的三種情況。下面我寫一下類Point,便于大家參考。

class  Point

{

   public:

            Point (int xx=0, int yy=0)                 // 構造函數,帶有形參

            {                 

                          x=xx;   y=yy;           

            }

            Point (Point &p);                           // 複制構造函數

            int getX() {   return x;   }

            ..........

   private:

             int x , y;

};

Point::Point(Point  &p)                 // 複制構造函數實作

             x=p.x;

             y=p.y;

}

繼續閱讀