以下这段程序有错误,是关于没有复制构造函数的错误,下面我们将解开这段程序错误之谜:
#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了。