深入浅拷贝和深拷贝。初学者的笔记

浅拷贝和深拷贝都是相对拷贝构造函数来讲的

下面代码实现浅拷贝,

 1 #include <stdio.h>
 2 #include <iostream>
 3 #include <string>
 4 using namespace std;
 5
 6 class A
 7 {
 8    public :
 9        A(int a=0):m_num(a){};
10        A(const A &arr);
11        int set_num();
12    private:
13      int m_num;
14 };
15
16 A::A(const A &arr)
17  {
18      m_num=arr.m_num;
19  }
20 int A::set_num()
21  {
22     return m_num;
23  }
24 int main (void)
25 {
26    A arr1(5);
27    A arr2(arr1);
28    cout << "arr1="<<arr1.set_num()<<endl<<"arr2="<<arr2.set_num()<<endl;
29 return 0;
30 }

再增加一个类成员指针变量,

 1 #include <stdio.h>
 2 #include <iostream>
 3 #include <string>
 4 using namespace std;
 5
 6 class A
 7 {
 8    public :
 9        A(int a=0)
10        {
11            cout <<"A"<<endl;
12         m_num=a;
13         m_a=new int[m_num];
14        };
15        A(const A &arr);
16        int set_num();
17        ~A();
18    private:
19      int m_num;
20      int *m_a;
21 };
22
23 A::A(const A &arr)
24  {
25       cout << "&A"<<endl;
26       m_a=arr.m_a;
27      m_num=arr.m_num;
28  }
29 int A::set_num()
30  {
31     return m_num;
32  }
33 A::~A()
34 {
35     cout << "~A"<<endl;
36     delete []m_a;
37 }
38 int main (void)
39 {
40    A arr1(5);
41    A arr2(arr1);
42    cout << "arr1="<<arr1.set_num()<<endl<<"arr2="<<arr2.set_num()<<endl;
43 return 0;
44 }

上面程序拷贝构造函数中把对象的指针地址拷贝给当前对象的指针地址,

当执行到析构函数,以为有两个对象,不是要删除两次吗,当运行第一次时没有问题,

当运行第二次程序就会崩溃。

那要解决这个问题就要深拷贝了。

 1 #include <stdio.h>
 2 #include <iostream>
 3 #include <string>
 4 using namespace std;
 5
 6 class A
 7 {
 8    public :
 9        A(int a=0)
10        {
11            cout <<"A"<<endl;
12         m_num=a;
13         m_a=new int[m_num];
14        };
15        A(const A &arr);
16        int set_num();
17        void set_m_a();
18        ~A();
19    private:
20      int m_num;
21      int *m_a;
22 };
23
24 void A::set_m_a()
25 {
26     for (int i=0;i<m_num;i++)
27     {
28         m_a[i]=i;
29         cout << "m_a["<<i<<"]="<<m_a[i]<<endl;
30     }
31
32 }
33 A::A(const A &arr)
34  {
35       m_num=arr.m_num;
36       cout << "&A"<<endl;
37       m_a=new int [arr.m_num];
38       for (int i=0;i<arr.m_num;i++)
39       {
40         m_a[i]=arr.m_a[i];
41       }
42
43
44  }
45 int A::set_num()
46  {
47     return m_num;
48  }
49 A::~A()
50 {
51     cout << "~A"<<endl;
52     delete []m_a;
53 }
54 int main (void)
55 {
56    A arr1(5);
57    A arr2(arr1);
58    cout << "arr1="<<arr1.set_num()<<endl<<"arr2="<<arr2.set_num()<<endl;
59    cout << "arr1.m_a=";arr1.set_m_a();
60    cout<<endl;
61    cout << "arr2.m_a=";arr2.set_m_a();
62 return 0;
63 }

這样对象之间的赋值就不是地址之间的赋值,也不会同块内存中释放两次。

时间: 2024-11-11 03:24:59

深入浅拷贝和深拷贝。初学者的笔记的相关文章

Python中的赋值,浅拷贝和深拷贝的区别

赋值 内存地址的引用,所有的改变都会同步 测试代码 #coding:utf-8 import copy a=['a','b',1,[1,2,3]] b = a #对象赋值,所有改动都会联动 a.append('d') a[0]='aaa' a[3].append(4) print a print b 运行结果 ['aaa', 'b', 1, [1, 2, 3, 4], 'd'] ['aaa', 'b', 1, [1, 2, 3, 4], 'd'] 浅拷贝 str,num等深浅拷贝都一样,list

c#中浅拷贝和深拷贝的理解

c#中拷贝有浅拷贝和深拷贝之分. 例如对象A,其中有值类型字段和引用类型字段: 1.浅拷贝: 对于值类型字段,直接逐位复制到新拷贝的副本对象中,修改副本的字段的值,不会影响源对象中字段的值: 对于引用类型字段,只复制字段的引用到副本对象中,引用的对象不复制,因为副本和源对象的字段引用的是同一个对象,所以修改副本对象中的字段会影响源对象. 实现:使用Object类MemberwiseClone实现. 2.深拷贝: 对于值类型字段,和浅拷贝的效果一样: 对于引用类型字段,不仅复制字段的引用到副本对象

浅拷贝、深拷贝

在项目中我们经常要处理数据,概括就四个字:增删改查, 我们"增删改查"操作数据其实也就操作内存数据,经常会各种变量互相赋值 那么问题来了,如果是普通的赋值其实也就是简单的浅拷贝数据, 浅拷贝容易被影响数据,深拷贝则不一样. 以下一个小例子: 为什么b数组删除一个下标,a数组也会被影响呢? 这里就涉及到浅拷贝.深拷贝 b数组的内容来自于a数组 如果a直接赋值b那么属于浅拷贝, 虽然它们变量名不一样但内存地址是一样的, 如果某一个变量改变了该内存值,那么其他变量也会受影响 解决方法是用深拷

js对象浅拷贝和深拷贝详解

js对象浅拷贝和深拷贝详解 作者:i10630226 字体:[增加 减小] 类型:转载 时间:2016-09-05我要评论 这篇文章主要为大家详细介绍了JavaScript对象的浅拷贝和深拷贝代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 本文为大家分享了JavaScript对象的浅拷贝和深拷贝代码,供大家参考,具体内容如下 1.浅拷贝 拷贝就是把父对像的属性,全部拷贝给子对象. 下面这个函数,就是在做拷贝: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 var

渐析java的浅拷贝和深拷贝

作者: chenssy 出处: http://www.cnblogs.com/chenssy/ 首先来看看浅拷贝和深拷贝的定义: 浅拷贝:使用一个已知实例对新创建实例的成员变量逐个赋值,这个方式被称为浅拷贝. 深拷贝:当一个类的拷贝构造方法,不仅要复制对象的所有非引用成员变量值,还要为引用类型的成员变量创建新的实例,并且初始化为形式参数实例值.这个方式称为深拷贝 也就是说浅拷贝只复制一个对象,传递引用,不能复制实例.而深拷贝对对象内部的引用均复制,它是创建一个新的实例,并且复制实例. 对于浅拷贝

正确实现浅拷贝和深拷贝

为对象创建副本的技术称为拷贝(也叫克隆).我们将拷贝分为浅拷贝和深拷贝. 浅拷贝:将对象中的所有字段复制到新的对象(副本)中.其中,值类型字段的值被复制到副本中后,在副本中的修改不会影响到源对象对应的值.而引用类型的字段被复制到副本中的是引用类型的引用,而不是引用的对象,在副本中对引用类型的字段值做修改会影响到源对象本身. 深拷贝:同样,将对象中的所有字段复制到新的对象中.不过,无论是对象的值类型字段,还是引用类型字段,都会被重新创建并赋值,对于副本的修改,不会影响到源对象本身. 无论是浅拷贝还

编写高质量代码改善C#程序的157个建议——建议14: 正确实现浅拷贝和深拷贝

建议14: 正确实现浅拷贝和深拷贝 为对象创建副本的技术称为拷贝(也叫克隆).我们将拷贝分为浅拷贝和深拷贝. 浅拷贝 将对象中的所有字段复制到新的对象(副本)中.其中,值类型字段的值被复制到副本中后,在副本中的修改不会影响到源对象对应的值.而引用类型的字段被复制到副本中的是引用类型的引用,而不是引用的对象,在副本中对引用类型的字段值做修改会影响到源对象本身. 深拷贝 同样,将对象中的所有字段复制到新的对象中.不过,无论是对象的值类型字段,还是引用类型字段,都会被重新创建并赋值,对于副本的修改,不

C++拷贝构造函数(浅拷贝、深拷贝)

下面举一个简单的例子说明对象之间的拷贝(此例中没有自定义拷贝构造函数,在调用拷贝构造函数的时候,编译器会自动生成一个默认的拷贝构造函数,该构造函数完成对象之间的位拷贝)浅拷贝: #include<iostream> using namespace std; class CExample { private:int a; public: CExample(int b) { a=b; } void Show() { cout<<a<<endl; } }; int main(

浅拷贝,深拷贝---ios

#import <Foundation/Foundation.h> @interface Father : NSObject <NSCopying,NSMutableCopying> @property (nonatomic,copy) NSString *name; @property (nonatomic,retain) NSNumber *age; -(id) initWithName:(NSString *)name withAge:(NSNumber *) age; @e