对于普通类型的对象来说,它们之间的复制是很简单的,例如:
int a=88;
int b=a; 
而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量。下面看一个类对象拷贝的简单例子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
using namespace std;
class CExample {
private:
     int a;
public:
     CExample(int b)
     { a=b;}
     void Show ()
     {
        cout<<a<<endl;
    }
};
int main()
{
     CExample A(100);
     CExample B=A;
     B.Show ();
     return 0;
}

运行程序,屏幕输出100。从以上代码的运行结果可以看出,系统为对象B分配了内存并完成了与对象A的复制过程。就类对象而言,相同类型的类对象是通过拷贝构造函数来完成整个复制过程的。下面举例说明拷贝构造函数的工作过程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
using namespace std;
class CExample {
private:
    int a;
public:
    CExample(int b)
    { a=b;}
     
    CExample(const CExample& C)
    {
        a=C.a;
    }
    void Show ()
    {
        cout<<a<<endl;
    }
};
int main()
{
    CExample A(100);
    CExample B=A;
    B.Show ();
    return 0;
}

当用一个已初始化过了的自定义类类型对象去初始化另一个新构造的对象的时候,拷贝构造函数就会被自动调用。也就是说,当类的对象需要拷贝时,拷贝构造函数将会被调用。以下情况都会调用拷贝构造函数:
(1)一个对象以值传递的方式传入函数体 
(2)一个对象以值传递的方式从函数返回 
(3)一个对象需要通过另外一个对象进行初始化。

如果在类中没有显式地声明一个拷贝构造函数,那么,编译器将会自动生成一个默认的拷贝构造函数,该构造函数完成对象之间的位拷贝。位拷贝又称浅拷贝,后面将进行说明。

自定义拷贝构造函数是一种良好的编程风格,它可以阻止编译器形成默认的拷贝构造函数,提高源码效率。
浅拷贝和深拷贝

  在某些状况下,类内成员变量需要动态开辟堆内存,如果实行位拷贝,也就是把对象里的值完全复制给另一个对象,如A=B。这时,如果B中有一个成员变量指针已经申请了内存,那A中的那个成员变量也指向同一块内存。这就出现了问题:当B把内存释放了(如:析构),这时A内的指针就是野指针了,出现运行错误。

  深拷贝和浅拷贝可以简单理解为:如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝。下面举个深拷贝的例子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
using namespace std;
class CA
{
 public:
  CA(int b,char* cstr)
  {
   a=b;
   str=new char[b];
   strcpy(str,cstr);
  }
  CA(const CA& C)
  {
   a=C.a;
   str=new char[a];//深拷贝
   if(str!=0)
    strcpy(str,C.str);
  }
  void Show()
  {
   cout<<str<<endl;
  }
  ~CA()
  {
   delete str;
  }
 private:
  int a;
  char *str;
};
int main()
{
 CA A(10,"Hello!");
 CA B=A;
 B.Show();
 return 0;
}

C++的深拷贝与浅拷贝相关推荐

  1. Python 精选笔试面试习题—类继承、方法对象、包管理、闭包、可变类型作为默认参数、列表引用、sort与sorted、 append 和 extend、深拷贝和浅拷贝

    1. 类继承 如下代码 class A(object):def show(self):print 'This is calss A'class B(A):def show(self):print 'T ...

  2. C++深拷贝与浅拷贝

    浅拷贝就是成员数据之间的一一赋值:把值赋给一一赋给要拷贝的值.但是可能会有这样的情况:对象还包含资源,这里的资源可以值堆资源,或者一个文件..当 值拷贝的时候,两个对象就有用共同的资源,同时对资源可以 ...

  3. python的深拷贝与浅拷贝

    对于list, set, dict来说, 直接赋值. 其实是把内存地址交给变量. 并不是复制⼀份内容. 两个变量的内容其实为一个地址,如果要在复制的同时分配新的地址则需要用到深拷贝和浅拷贝的命令 ls ...

  4. 详谈Javascript中的深拷贝和浅拷贝

    数据复制是我们编程中经常会使用到的技术,对于普通数值数据来说,复制很简单,但是对于复杂类型比如对象的复制,就会有很多需要考虑的东西,比如我们经常说到的深拷贝和浅拷贝. 浅拷贝 复制的对象和原始对象属性 ...

  5. python怎么避免浅拷贝_详谈Python中的深拷贝和浅拷贝

    在平时工作中,经常涉及到数据的传递,在数据传递使用过程中,可能会发生数据被修改的问题.为了防止数据被修改,就需要在传递一个副本,即使副本被修改,也不会影响原数据的使用.为了生成这个副本,就产生了拷贝. ...

  6. c++深拷贝和浅拷贝

    C++中类的拷贝有两种:深拷贝,浅拷贝:当出现类的等号赋值时,即会调用拷贝函数 一:两个的区别 1 在未定义显示拷贝构造函数的情况下,系统会调用默认的拷贝函数--即浅拷贝,它能够完成成员的一一复制.当 ...

  7. 更清晰的认识对象——深拷贝与浅拷贝

    对象在引用的时候引用的是对象的地址,所以导致如果修改其中一个对象,就会对其他引用这个地址的对象进行修改,这种结果并不是我们想要的,这个时候我们就要用到深拷贝和浅拷贝去解决这个问题了. var a = ...

  8. 深拷贝与浅拷贝~动态内存释放有关

    浅拷贝就是对象的数据成员之间的简单赋值,如你设计了一个没有类而没有提供它的复制构造函数,当用该类的一个对象去给令一个对象赋值时所执行的过程就是浅拷贝,如: class A{ public: A(int ...

  9. 深入浅出的“深拷贝与浅拷贝”

    js中的浅拷贝与深拷贝,只是针对复杂数据类型(object, Array)的复制问题.浅拷贝和深拷贝都可以实现在已有对象上再生出一份的作用.但是对象的实例是存储在堆内存中然后通过一个引用值只操作对象, ...

  10. Javascript中的深拷贝和浅拷贝

    文章目录 JavaScript中的变量类型 深拷贝和浅拷贝的理解 深拷贝和浅拷贝的实现方式 为什么需要深拷贝和浅拷贝 JavaScript中的变量类型 (1).基本类型 JavaScript中的基本类 ...

最新文章

  1. [原]tornado源码分析系列(三)[网络层 IOLoop类]
  2. NeurIPS | 2019 机器学习领域最新十篇论文,来自谷歌、Facebook、普林斯顿大学、斯坦福大学等团队的最新研究成果...
  3. STC自动高速下载线
  4. python做方差分析和卡方检验
  5. 算法1:找出第一个非重复字符在字符串中的位置
  6. hive中任意相邻时间段数据获取
  7. JavaEE概念简介
  8. matlab中m文件与m函数的学习与理解
  9. LeetCode 530二叉搜索树的最小绝对差
  10. 分析java 嵌套类与内部类
  11. 计算机主板性能由什么决定,电脑内存条频率取决于CPU还是主板?
  12. html5%3chr%3e的样式,Vbs脚本编程简明教程
  13. 台式电脑主板插线步骤图_台式电脑主板接线图解
  14. pinyin4j获取汉字正确的全拼和简拼
  15. 教你轻松快速学会用Calibre TXT转MOBI
  16. 2014 史丰收速算
  17. 关于虚拟主机那点事儿
  18. 基于Pacemaker+Corosync的PostgreSQL HA故障两例
  19. 声纹识别概述(3)声纹识别系统
  20. viso画图时如何让右侧显示设置形状格式栏

热门文章

  1. SpringBoot_配置-@Conditional自动配置报告
  2. word2vec相似度计算_文档相似度助力搜索引擎
  3. 有n个人围成一圈,按顺序从1到n编号。从第一个人开始报数
  4. exit()函数学习
  5. 剑指offer 回溯法 面试题12 矩阵中的路径 面试题13 机器人的运动范围
  6. js 对 URL 参数进行 加密 解密
  7. RxJava系列四(过滤操作符)
  8. 使用subgit进行svn迁移至git(branch,tags)
  9. Docker相关的项目
  10. 神奇的事情,不同进程监听同一个端口,居然都成功