由push_back引起的複製構造函數

以下這段程序有錯誤,是關於沒有複製構造函數的錯誤,下面我們將解開這段程序錯誤之謎:

#include <string.h>
#include <vector>
#include <iostream>
using namespace std;
int i=0;
int j=0;
class CDemo
{
    public:
        CDemo():str(NULL){cout<<"constructor_"<<i++<<endl;};
        //註釋掉下面這段複製構造函數
        //CDemo(const CDemo &cd){cout<<"constructor_"<<i++<<endl;this->str=new char[strlen(cd.str)+1];strcpy(str,cd.str);};
        ~CDemo(){cout<<"destrcutor_"<<j++<<endl;if(str) delete []str;};
        char *str;
};

int main()
{
    CDemo d1;
    d1.str=new char[32];
    strcpy(d1.str,"hello_a_world");
    vector<CDemo> *a1=new vector<CDemo>();
    a1->push_back(d1);//×××××××××關鍵語句
    delete a1;
}
源代碼中已經標出了關鍵語句,這段語句中主要函數是屬於vector的push_back,下面看看push_back源碼:

void push_back(const T &x)
{
   if(finish!=end_of_storage)
   {
      construct(finish,x);
      ++finish;
   }
   else//如果備用空間不足
   {
      insert_aux(end(),x);
   }
}
constuct函數的原型如下:

template<class T1,class T2>
inline void construct(T1 *p,const T2&value)
{
  new (p)T1(value);
} 
好了,上一篇文章(定位new表達式)已經列出來了,這裏是一個定位new表達式,那麼算法深入到這一步,我們到底是需要什麼呢?首先new(p)T1(value)中,p是個指針,或者說是個迭代器,這個指針所指的類型是T1,那麼在本例中T1是什麼呢?是CDemo;T2的類型是什麼呢?也是CDemo,好了,new是要初始化這片內存的,應該選用哪個構造函數呢,很顯然是一個像下面這樣的複製構造函數了:

CDemo(const CDemo &cd){};
但是,源程序裏面是沒有這段函數的,所以會報錯。因此只要在源代碼把註釋符去掉一切就都OK了。






發佈了58 篇原創文章 · 獲贊 20 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章