当用一个已经初始化过了的自定义类类型对象去初始化另一个新构造的对象的时候,拷贝构造函数就会被自动调用,如果你没有自定义拷贝构造函数的时候系统将会提供给一个默认的拷贝构造函数来完成这个过程。
简单来说就是以一个已存在的对象为模型创建一个新对象
拷贝构造函数的两种调用形式:
(a)A a;
A a1 = a; //隐式调用拷贝构造函数
(b)A a1;
A a2(a1); //显式调用拷贝构造函数
默认拷贝构造函数,执行的是简单的内存拷贝 --- 浅拷贝
(1)浅拷贝
只拷贝地址,而不是对指针指向空间的拷贝,会造成2个指针指向同一个空间
(2)深拷贝
为指针创建新空间,拷贝指针指向空间的内容,注意关键是成员属性值的拷贝。
声明形式:
Person(const Person & p){...}
拷贝构造函数是一类特殊的构造函数,是在用同一类型的对象初始化一个新生成的对象时被调用的。这样,如果拷贝构造函数的参数不是引用的话,那参数传递是值传递的过程,其实就是一个初始化的过程,而且同类型的对象初始化另一对象,因此这个过程中又要调用拷贝构造函数……这是一个无限循环的过程。为了避免这个问题,拷贝构造函数的参数必须是引用。
情况1:调用默认拷贝函数
class Person{
int n;
public:
Person(int n=0):n(n){ cout<<"Person()"<<endl; }
~Person(){ cout<<"~Person() "<<endl;}
void speak(){ cout<<"hello"<<n<<<endl; }
void setN(int n){
this->n=n;//区分于java中的this.n写法
}
};
void fn( Person p ){
p.speak();
}
int main(){
Person p ;
p.setN(5);
p.speak();
fn( p ) ;
return 0 ;
}
结果是:
Person()
Hello5
Hello5
~Person()
~Person()
注意:调用了两次析构,只创建了一个对象
情况2:自己写一个拷贝构造函数
Person(const Person &p){
n=p.n;//不加这句话的后果是没有实现成员变量的拷贝
}