1 简介
1.1 概念
复制构造函数(copy constructor)是一种特殊的构造函数,具有单个形参,该形参(常用const修饰)是对该类类型的引用。当定义一个新对象并用一个同类型的对象对它进行初始化时,将显式使用复制构造函数。
1.2 格式
假设类的名称是Foo,则Foo类的复制构造函数的声明为
class Foo{
public:
Foo(); //默认构造函数
Foo(const Foo&); //复制构造函数
//....
}
1.3 默认的复制构造函数
如果类中没有定义复制构造函数,则编译器会生成一个默认的复制构造函数。默认的复制构造函数将类的成员进行逐个初始化。
2 应用
假设Foo类的如1.2中格式声明,有如下代码
1 Foo f1;
2 Foo f2 = f1;
则第1行中调用的是Foo类的默认构造函数,第2行中调用的是Foo的复制构造函数。
3 实战
在CSDN论坛中有朋友问到这样一个问题:自定义类mystring中,定义了该类的复制构造函数
mystring::mystring(mystring&another)
{
if(str!=NULL)
delete[]str;
str = new char[strlen(another.str)+1];
strcpy(str,another.str);
}
而str是mystring类的成员变量,其定义为
char* str;
之后在main()函数中,有如下代码
mystring s1("Hello");
mystring s2=s1;
此时的程序编译没有错误,而在程序运行到mystring s2=s1;代码时报错。报错的主要原因是mystring s2=s1;实际上调用了mystring类的复制构造函数,在该类的复制构造函数中,首先判断str是否为NULL,如果不是,则调用delete来释放内存。由于str在定义是并没有进行初始化,此时str的值是0xcccccccc,并不等于NULL,接下来在释放0xcccccccc位置处的内存时,程序就会报错。
由于复制构造函数也属于构造函数,此时需要对成员变量进行初始化处理。因此,可以在复制构造函数的初始化列表中对str进行初始化的处理
mystring::mystring(mystring&another)
:str(NULL)
{
.........
}