一、调用拷贝构造函数的时机:
1、使用一个已经创建完毕的对象来初始化一个新对象
2、值传递的方式给函数参数传值
3、以值方式返回局部对象
class Person
{
public:
Person()
{
cout << "默认构造" << endl;
}
Person(int age)
{
m_Age = age;
cout << "有参构造" << endl;
}
Person(Person p)
{
m_Age = p.age;
cout << "拷贝构造" << endl;
}
~Person()
{
cout << "析构函数" << endl;
}
private:
int m_Age;
}
//1、使用一个已经创建完毕的对象来初始化一个新对象
void test01()
{
Person p1(20);
Person p2(p1);
}
//2、值传递的方式给函数参数传值
void work(Person P)
{
//拷贝一个新的副本传入 不影响原副本
}
void test02()
{
Person p;
work();
}
//3、以值方式返回局部对象
Person work2()
{
Person p1;//函数执行完毕后会释放对象
cout << "查看当前p1地址" << (int*)&p1<< endl;
return p1;//返回的是根据p1创建的新副本对象
}
void test03()
{
Person p = work2();
cout << "查看当前p1地址" << (int*)&p<< endl;
}
二、深拷贝和浅拷贝
浅拷贝:简单赋值拷贝操作
深拷贝:在堆区重新申请空间,进行拷贝操作
class Person
{
public:
Person()
{
cout << "默认构造函数" << endl;
}
Person(int a,int h)
{
age = a;
H = new int(h);
cout << "有参构造函数" << endl;
}
~Person()
{
//将堆区开辟的数据做释放操作
if(H != NULL)
{
delete H;
H = NULL;
}
cout << "析构函数" << endl;
}
private:
int age;
int *H;
}
void test()
{
Person p1(18,160);
cout << "p1年龄:" << p1.age << "身高:" << *p1.H << endl;
//浅拷贝
Personp2(p1); //栈先进后出 p2先被析构释放
cout << "p2年龄:" << p2.age << "身高:" << *p2.H << endl;
}
** 此时浅拷贝会出现内存重复释放错误 **
** p2先行释放堆区,此时堆区已经被清空,p1接着释放堆区,进行非法操作 **
** 可利用深拷贝解决该问题 **
** 自己实现拷贝构造函数解决该问题 **
class Person
{
public:
Person()
{
cout << "默认构造函数" << endl;
}
Person(int a,int h)
{
age = a;
H = new int(h);
cout << "有参构造函数" << endl;
}
Person(const Person p)
{
cout << "拷贝构造函数" << endl;
age = p.age;
//深拷贝操作
H = new int(*p.H);
}
~Person()
{
//将堆区开辟的数据做释放操作
if(H != NULL)
{
delete H;
H = NULL;
}
cout << "析构函数" << endl;
}
private:
int age;
int *H;
}
void test()
{
Person p1(18,160);
cout << "p1年龄:" << p1.age << "身高:" << *p1.H << endl;
//浅拷贝
Personp2(p1); //栈先进后出 p2先被析构释放
cout << "p2年龄:" << p2.age << "身高:" << *p2.H << endl;
}