浅拷贝:简单的赋值拷贝操作
深拷贝:在堆区重新申请空间,进行拷贝操作
下面这段代码即为简单的浅拷贝操作,在程序员为定义拷贝构造函数的时候,编译器会调用默认的拷贝构造函数进行拷贝(默认的拷贝构造函数为浅拷贝,即不能对堆区的内容进行拷贝)
#include <iostream>
using namespace std;
class People
{
public:
//无参构造函数
People()
{
m_name = "";
m_age = 0;
cout << "无参构造" << endl;
}
//初始化列表
People(string name, int age):m_name(name),m_age(age)
{
cout << "带参构造" << endl;
}
~People()
{
cout << "析构函数" << endl;
}
string ShowName()
{
return m_name;
}
int ShowAge()
{
return m_age;
}
private:
string m_name;
int m_age;
};
void test1()
{
People p1("pw", 21);
cout << "name = " << p1.ShowName() << " age = " << p1.ShowAge() << endl;
People p2(p1);
cout << "name = " << p2.ShowName() << " age = " << p2.ShowAge() << endl;
}
int main(int argc, char *argv[])
{
test1();
return 0;
}
这段代码就是简单的将p1的m_name以及m_age赋值给p2,并打印内容
运行结果:

但是在创建构造函数的时候,申请了堆区资源,浅拷贝就会发生错误,需要自己定义一个拷贝函数,即深拷贝
对深拷贝构造函数的实现:
#include <iostream>
using namespace std;
class People
{
public:
//无参构造函数
People()
{
m_name = "";
m_age = 0;
m_height = NULL;
cout << "无参构造" << endl;
}
//初始化列表
People(string name, int age, int height)
{
m_name = name;
m_age = age;
m_height = new int(height); //申请资源,并赋值height
cout << "带参构造" << endl;
}
~People()
{
delete m_height; //关闭开辟的堆区空间
m_height = NULL;
cout << "析构函数" << endl;
}
string ShowName()
{
return m_name;
}
int ShowAge()
{
return m_age;
}
int ShowHeight()
{
return *m_height;
}
#if 1
People(const People &p) //const防止修改内容
{
m_name = p.m_name;
m_age = p.m_age;
m_height = new int(*p.m_height);
cout << "自己创建的拷贝构造函数" << endl;
}
#endif
private:
string m_name;
int m_age;
int *m_height;
};
void test1()
{
People p1("pw", 21, 175);
cout << "name = " << p1.ShowName() << " age = " << p1.ShowAge() << " height = " << p1.ShowHeight() << endl;
People p2(p1);
cout << "name = " << p2.ShowName() << " age = " << p2.ShowAge() << " height = " << p2.ShowHeight() << endl;
}
int main(int argc, char *argv[])
{
test1();
return 0;
}
如果使用编译器提供的拷贝构造函数(浅拷贝),运行结果为:

如果使用自己创建的拷贝构造函数(深拷贝),运行结果为:

出现这样的原因是因为,当我们没有定义拷贝构造函数时,会在拷贝对象时调用默认拷贝构造函数,进行浅拷贝,即对指针拷贝后会出现两个指针指向同一个内存空间,所以在释放资源的时候,会对同一片空间释放两次,从而导致程序崩溃,而我们自己定义的拷贝构造函数,是申请了两片堆区空间,p1、p2分别释放自己相对应的堆区空间,所以程序正常运行。
总结:在定义一个类的时候,运用到了堆区空间,拷贝构造函数应该自己定义。
本文探讨了C++中浅拷贝和深拷贝的概念,通过示例代码展示了默认拷贝构造函数(浅拷贝)可能导致的问题及解决方法——自定义深拷贝构造函数。当类中涉及堆区资源时,不正确的拷贝构造函数可能导致内存泄漏或程序崩溃。正确实现深拷贝能确保每个对象独立管理自己的堆区资源,避免副作用。
2088

被折叠的 条评论
为什么被折叠?



