现在的位置: 首页 > 综合 > 正文

由push_back引起的复制构造函数

2013年09月11日 ⁄ 综合 ⁄ 共 1079字 ⁄ 字号 评论关闭

以下这段程序有错误,是关于没有复制构造函数的错误,下面我们将解开这段程序错误之谜:

#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了。

抱歉!评论已关闭.