一.拷贝构造函数:
就是用已存在的类类型对象创建新对象时由编译器自动调用 d2(d1)。
对于一些普遍类的拷贝构造,系统拷贝构造(浅拷贝)就可以了,但是对于stack这种类需要深拷贝,所以就需要我们自己写拷贝构造。
二.参数类型:
只有单个形参,其唯一形参必须是引用,但并不限制为const,一般普遍的会加上const限制。不能使用值传递。
1.为什么不能使用值传递。
原因:调用拷贝构造,如果进行传值传参的话,在传参过程中,又需要对对象进行拷贝构造,如此往复就会引发无穷递归。
2.为什么要加const限制
原因:拷贝构造函数的目的是用其它对象的数据来初始化当前对象,不期望更改其它对象的数据。
三.深浅拷贝:
#include<iostream>
using namespace std;
class Person {
public:
Person() //无参默认构造函数
{
cout << "默认构造函数" << endl;
}
Person(int age, int height)
{
m_Age = age;
m_Height = new int(height);//浅拷贝将height地址值赋值m_Height
cout << "有参" << endl;
}
~Person()
{
if (m_Height != NULL)
{
delete m_Height;//结束后释放
m_Height = NULL;//为空
}
cout << "析构" << endl;
}
Person(const Person& p)
{
cout << "拷贝构造函数" << endl;
m_Age = p.m_Age;
m_Height = new int(*p.m_Height);//深拷贝,复制指针指向内容,为m_Height分配新空间
}
int m_Age;
int* m_Height;
};
int main()
{
Person p1(18, 160);
cout << p1.m_Age << "::" << *p1.m_Height << endl;
Person p2(p1);
cout << p2.m_Age << "::" << *p2.m_Height << endl;
return 0;
}
浅拷贝:只是将指针的地址赋值给新对象,两个对象共用一块地址空间,共享数据,其中一个对象修改数据,另一个数据也会被修改,不安全。并且程序结束析构时,该地址空间会被析构两次。
p2析构成功,p1析构失败
深拷贝:重新开辟了一块地址空间,内容格式与拷贝对象一模一样,且两者完全独立的,分别拥有自己的数据和资源,其中一个对象修数据被修改,另一个数据不会被修改。
四.调用的几种情况:
1.用已经构造好的对象来初始化另一个同类的对象。
2.函数的参数为类的对象:
在调用函数时需要将实参对象完整地传递给形参,也就是需要建立一个实参的拷贝,类似于----
Date d(d1);系统就调用Date的拷贝构造来实现,这样,能够保证形参具有和实参完全相同的值。
3.函数的返回值是类的对象:
调用func2函数结束时,对象d的生命周期就结束了,不是d赋值给了d1,而是在结束前执行return语句时,就调用了Date的拷贝构造复制了一个临时对象,然后把它赋值给了d1。