大家好,我是KookNut39,在CSDN写文,分享一些自己认为在学习过程中比较重要的东西,致力于帮助初学者入门,希望可以帮助你进步。最近在更新C/C++方面的知识,感兴趣的欢迎关注博主,可以去专栏查看之前的文章,希望未来能和大家共同探讨技术。
C++类对象的赋值操作分为深拷贝和浅拷贝两种,我们所说的的浅拷贝就是赋值操作,这种拷贝比较常见,比如:
class A {
public: A(); ~A(); public: int i; }; A::A() {
i = 5; } A::~A() {
} void main() {
A a1;//执行默认构造函数 初始化a1.i = 7 A a2 = a1;//发生赋值操作 此刻a2.i = 5 a2.i = 7;//只修改a2中的成员,对a1中的不造成影响 return; }
class A {
public: A(); ~A(); public: char* ptr1; }; A::A() {
ptr1 = new char[5]; memset(ptr1, 'h', 5); } A::~A() {
if (ptr1 != nullptr) {
delete[]ptr1; ptr1 = nullptr; } } void main() {
A a1;//执行默认构造函数 A a2 = a1;//发生赋值操作 return; }
涉及到动态内存的分配与释放的时侯就比较危险,可能会造成对内存的二次释放,出现内存堆被破坏,导致内存奔溃的情况发生!这是为什么呢?我们上述代码中,对于类对象的赋值是简单的拷贝操作,也就是直接把a1中申请的那块内存的值复制给了a2中的ptr1对象,它相当于做了这样一个操作:
a2.ptr1 = a1.ptr1;
但是我们可以用深拷贝来解决这个问题!
class A {
public: A();//默认构造函数 A(const A& A1);//拷贝构造函数 ~A(); public: char* ptr1; }; A::A() {
ptr1 = new char[5]; memset(ptr1, 'h', 5); } A::A(const A &A1) {
ptr1 = new char[5]; strcpy(ptr1, A1.ptr1); } A::~A() {
if (ptr1 != nullptr) {
delete[]ptr1; ptr1 = nullptr; } } void main() {
A a1;//执行默认构造函数 A a2 = a1;//发生深拷贝赋值操作,另外开辟了内存空间 A a3(a1);//发生深拷贝赋值操作,另外开辟了内存空间 return; }
码字不易,如果喜欢,赏个点赞+评论+收藏???,感谢您的支持
惯例今日吟诗好几句:“多情自古伤离别,更那堪,冷落清秋节!今宵酒醒何处?杨柳岸,晓风残月。此去经年,应是良辰好景虚设。便纵有千种风情,更与何人说?”
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/220628.html原文链接:https://javaforall.net
