C++ 拷貝構(gòu)造函數(shù)

C++ 類 & 對象C++ 類 & 對象

什么是拷貝構(gòu)造函數(shù)

首先對于普通類型的對象來說,它們之間的復(fù)制是很簡單的,例如:

int a = 100;
int b = a; 

而類對象與普通對象不同,類對象內(nèi)部結(jié)構(gòu)一般較為復(fù)雜,存在各種成員變量。
下面看一個類對象拷貝的簡單例子。

#include <iostream>
using namespace std;

class CExample {
private:
     int a;
public:
      //構(gòu)造函數(shù)
     CExample(int b)
     { a = b;}

      //一般函數(shù)
     void Show ()
     {
        cout<<a<<endl;
      }
};
int main()
{
     CExample A(100);
     CExample B = A; //注意這里的對象初始化要調(diào)用拷貝構(gòu)造函數(shù),而非賦值
     B.Show ();
     return 0;
}

運(yùn)行程序結(jié)果為:

100

從以上代碼的運(yùn)行結(jié)果可以看出,系統(tǒng)為對象 B 分配了內(nèi)存并完成了與對象 A 的復(fù)制過程。就類對象而言,相同類型的類對象是通過拷貝構(gòu)造函數(shù)來完成整個復(fù)制過程的。

拷貝構(gòu)造函數(shù)是一種特殊的構(gòu)造函數(shù),它在創(chuàng)建對象時,是使用同一類中之前創(chuàng)建的對象來初始化新創(chuàng)建的對象??截悩?gòu)造函數(shù)通常用于:

  • 通過使用另一個同類型的對象來初始化新創(chuàng)建的對象。

  • 復(fù)制對象把它作為參數(shù)傳遞給函數(shù)。

  • 復(fù)制對象,并從函數(shù)返回這個對象。

如果在類中沒有定義拷貝構(gòu)造函數(shù),編譯器會自行定義一個。如果類帶有指針變量,并有動態(tài)內(nèi)存分配,則它必須有一個拷貝構(gòu)造函數(shù)??截悩?gòu)造函數(shù)的最常見形式如下:

classname (const classname &obj) {
   // 構(gòu)造函數(shù)的主體
}

在這里,obj 是一個對象引用,該對象是用于初始化另一個對象的。

#include <iostream>

using namespace std;

class Line
{
   public:
      int getLength( void );
      Line( int len );             // 簡單的構(gòu)造函數(shù)
      Line( const Line &obj);  // 拷貝構(gòu)造函數(shù)
      ~Line();                     // 析構(gòu)函數(shù)

   private:
      int *ptr;
};

// 成員函數(shù)定義,包括構(gòu)造函數(shù)
Line::Line(int len)
{
    cout << "Normal constructor allocating ptr" << endl;
    // 為指針分配內(nèi)存
    ptr = new int;
    *ptr = len;
}

Line::Line(const Line &obj)
{
    cout << "Copy constructor allocating ptr." << endl;
    ptr = new int;
   *ptr = *obj.ptr; // copy the value
}

Line::~Line(void)
{
    cout << "Freeing memory!" << endl;
    delete ptr;
}
int Line::getLength( void )
{
    return *ptr;
}

void display(Line obj)
{
   cout << "Length of line : " << obj.getLength() <<endl;
}

// 程序的主函數(shù)
int main( )
{
   Line line(10);

   display(line);

   return 0;
}

當(dāng)上面的代碼被編譯和執(zhí)行時,它會產(chǎn)生下列結(jié)果:

Normal constructor allocating ptr
Copy constructor allocating ptr.
Length of line : 10
Freeing memory!
Freeing memory!

下面的實(shí)例對上面的實(shí)例稍作修改,通過使用已有的同類型的對象來初始化新創(chuàng)建的對象:

#include <iostream>

using namespace std;

class Line
{
   public:
      int getLength( void );
      Line( int len );             // 簡單的構(gòu)造函數(shù)
      Line( const Line &obj);  // 拷貝構(gòu)造函數(shù)
      ~Line();                     // 析構(gòu)函數(shù)

   private:
      int *ptr;
};

// 成員函數(shù)定義,包括構(gòu)造函數(shù)
Line::Line(int len)
{
    cout << "Normal constructor allocating ptr" << endl;
    // 為指針分配內(nèi)存
    ptr = new int;
    *ptr = len;
}

Line::Line(const Line &obj)
{
    cout << "Copy constructor allocating ptr." << endl;
    ptr = new int;
   *ptr = *obj.ptr; // copy the value
}

Line::~Line(void)
{
    cout << "Freeing memory!" << endl;
    delete ptr;
}
int Line::getLength( void )
{
    return *ptr;
}

void display(Line obj)
{
   cout << "Length of line : " << obj.getLength() <<endl;
}

// 程序的主函數(shù)
int main( )
{
   Line line1(10);

   Line line2 = line1; // 這里也調(diào)用了拷貝構(gòu)造函數(shù)

   display(line1);
   display(line2);

   return 0;
}

當(dāng)上面的代碼被編譯和執(zhí)行時,它會產(chǎn)生下列結(jié)果:

Normal constructor allocating ptr
Copy constructor allocating ptr.
Copy constructor allocating ptr.
Length of line : 10
Freeing memory!
Copy constructor allocating ptr.
Length of line : 10
Freeing memory!
Freeing memory!
Freeing memory!

C++ 類 & 對象C++ 類 & 對象