在C++中,只有单个形参,而且该类型是对本类类型的引用(常用const修饰),这样的构造函数称为复制构造函数。
复制构造函数既可以自己定义又可以像默认构造函数一样被编译器隐式调用。但大多数时候,特别是类中有指针成员的时候要实现深复制,避免浅复制时,就需要自己定义复制构造函数。
那么我们定义的复制构造函数什么时候调用呢,总结起来,有如下五种情况,下面分别举例说明。
一、根据一个同类型对象显示或隐式初始化一个对象。
例如:
string str1 = “123456”;//copy-initialization
string str2(str1);//copy-initialization
string str3(10, '1‘);//direct-initialization
用“=”时,都是采用复制构造函数,具体过程是先用相应构造函数创建临时对象,然后采用copy构造复制过去。
二、复制一个对象将它作为实参传给一个函数。
例如:
class A{
};
A f(A a)
{
return a;
}
a作为非引用实参传递给函数f,形参a将被初始化为实参的一个副本,这时调用copy构造。
三、从函数返回时复制一个对象。
例如:
class A{
};
A f(A a)
{
return a;
}
跟上例一样,但这次要说的是返回值,因为返回的是非引用,所以要将a复制一份返回,所以此时也调用copy构造。
四、初始化顺序容器中的元素。
我们知道,容器中元素的初始化都是复制初始化,所以不能复制的对象是不可以存到容器中的,例如io对象。
既然是复制,那么将一个类对象放入容器中的时候就会调用copy构造。
例如:
vector
str_vec先用string默认构造创建一个临时值来初始化str_vec,然后用使用copy构造将临时值复制到str_vec的每个元素。
五、根据元素初始化式列表初始化数组元素。
例如:
string strs[] = { string(“ronnie”), string(“john”), string(“mark”) };
在以上数组中,数组元素将是用三个字符串的副本。