C++深拷贝简单介绍

对于一般的对象比如

int a = 10;
int b = 20;

对象间的赋值,复制过程很简单,但对于类对象来说,其内部存在着各种各样类型变量,其拷贝过程比较复杂。事实上,在对象拷贝过程中。如果没有自定义拷贝构造函数,系统会提供一个默认的拷贝构造函数,缺省的拷贝构造函数对于基本类型的成员变量,按字节复制,对于类类型的成员变量,调用其相应得拷贝构造函数,原型如下:

string(const string& that){}

这对于一般的类型变量拷贝没有问题,但如果类中含有指针类型的变量使用系统的缺省拷贝构造函数,就会出现问题,因为缺省的拷贝构造函数是按字节复制的,对于指针类型的成员变量只复制指针本身,而不复制指针向的对象这被称为浅拷贝,浅拷贝会带来指针被重复释放的问题,在运行阶段会出现断错误。比如如下代码

#include<iostream>
#include<cstring>
using namespace std;
class String {
public:
 String (const char* psz=NULL) : m_psz(strcpy(new char[strlen(psz?psz:"")+1],(psz?psz:""))){
  cout << "String构造" << endl;
 }
 ~String () {
  if(m_psz) {
   delete[] m_psz;
   m_psz = NULL;
  }
  cout << "String析构" << endl;
 }
 char* c_str(void) {
  return m_psz;
 }
private:
 char* m_psz;
};
int main(void) {
 String s1("hello");
 String s2(s1);
 cout << "s1    " << s1.c_str() << endl;
 cout << "s2    " << s2.c_str() << endl;
 s1.c_str()[0] = ‘H‘;
 cout << "s1    " << s1.c_str() << endl;
 cout << "s2    " << s2.c_str() << endl;
 return 0;
}
上述代码中,s1,s2对象中的m_psz指针指向同一块内存区域"hello",所以将s1中的m_psz指向的内存区域的第一个字符改为大写的"H",s2输出也是大写“H”,而且更要命的是当对象释放的时候,该内存会被释放两次导致程序崩溃。
在程序中加入我们自己定义的拷贝构造函数,如下
String (const String& that) : m_psz(strcpy((new char[strlen(that.m_psz)+1]),that.m_psz)){
  cout << "String拷贝构造" << endl;
 }
这样再运行就没有问题了。
当函数存在对象型的参数或对象型的返回值时都会用到拷贝构造函数。
 
而拷贝赋值的情况基本上与拷贝复制是一样的。只是拷贝赋值是属于操作符重载问题。
 我们可以自定义拷贝赋值函数如下:
void operator=(const String& that) {
    m_psz = strcpy (new char[strlen(that.m_psz)+1],that.m_psz);
}

这样考虑的问题太少,我们知道对于普通变量来讲a=b返回的是左值a的引用,所以它可以作为左值继续接收其他值(a=b)=30,这样来讲我们操作符重载后返回的应该是类对象的引用(否则返回值将不能作为左值来进行运算)
所以下面这一种实现方式是普遍采用的方式
String& operator=(cosnt String& that) {
    if(&that != this) {
        char *psz = strcpy (new char[strlen(that.m_psz)+1],that.m_psz);//如果失败会抛出异常,m_psz最后在析构函数里释放
        delete[] m_psz;
        m_psz = psz;  
    }
    return *this;
}

时间: 2024-10-18 02:29:55

C++深拷贝简单介绍的相关文章

python的列表,元组和字典简单介绍

引 入 java                                   python 存取多个值:数组或list集合 ------------------------> 列表,元组 key-value格式:    Map        ------------------------>    字典 自己学习发现,java跟python这两门面向对象语言在数据类型的定义上,很多思想都是互通的,这里不说java,简单介绍一下python的列表,元组和字典. 一.列表 List: 最通

javascript的return语句简单介绍

javascript的return语句简单介绍:return语句在js中非常的重要,不仅仅具有返回函数值的功能,还具有一些特殊的用法,有个清晰的把握是非常有必要的.下面就结合实例简单介绍一下return语句的作用.一.用来返回控制和函数结果:通常情况,return语句对于一个函数是很有必要的,因为往往需要函数在一系列的代码执行后会得到一个期望的返回值,而此值就是通过return语句返回,并且将控制权返回给主调函数.语法格式: return 表达式 代码实例如下: function add(){

Object-c集合的简单介绍

一.简单介绍 NSArray/NSMutableArray NSSet/NSMutableSet NSDictionary/NSMutableDictionary NSArray.NSSet.NSDictionary是不可变的,创建的时候初始化 NSMutableArray.NSMutableSet.NSMutableDictionary是可变的 二.使用介绍 NSArray是有序的数组 NSMutableArray *myArray=[[NSMutableArray alloc] init];

plsql的环境与介绍:环境的搭建和plsql的简单介绍

PLSQL编程 1.环境的搭建 (1)创建一个存储表空间 SQL> conn /as sysdbaConnected. SQL> create tablespace plsql datafile '/u01/oracle/oradata/ORCL/plsql01.dbf' size 1G; Tablespace created. (2)创建PLSQL用户SQL> create user plsql identified by plsql default tablespace plsql;

CSS之box-sizing的用处简单介绍

前几天才发现有 box-sizing 这么个样式属性,研究了一番感觉很有意思, 通过指定容器的盒子模型类型,达到不同的展示效果 例如:当一个容器宽度定义为 width:100%;  之后,如果再增加 padding 或者 border 则会溢出父容器,是向外扩张的 如果使用该样式,指定为 box-sizing: border-box; 则 padding 和 border 就不会再溢出,而是向内收缩的,这个效果感觉非常实用, 特别是 input 和 textarea 等 现在设置 100% 再直

【玩转微信公众平台之七】 PHP语法简单介绍

经过多篇的努力,我们终于成为了微信公众平台的开发者.但是别高兴的太早,就跟修真小说一样:修炼多年武破虚空,飞升到仙界后本以为成为了天仙即可跳出三界外,不在五行中.可实际到了仙界才发现,成仙只是修行的第一步......没错,成为开发者也才只是第一步,因为现在你的微信公众平台还没有任何功能,说难听点就是小白,说好听点就是白马王子,说可爱点就是小白白,说黄色点就是洗白白,说...----------------要想在微信公众平台添加功能,那就需要写代码:既然说到写代码,那么肯定是要用php(如果用AS

Zookeeper简单介绍

转自:ZooKeeper学习第一期---Zookeeper简单介绍 一.分布式协调技术 在给大家介绍ZooKeeper之前先来给大家介绍一种技术--分布式协调技术.那么什么是分布式协调技术?那么我来告诉大家,其实分布式协调技术 主要用来解决分布式环境当中多个进程之间的同步控制,让他们有序的去访问某种临界资源,防止造成"脏数据"的后果.这时,有人可能会说这个简单,写一个调 度算法就轻松解决了.说这句话的人,可能对分布式系统不是很了解,所以才会出现这种误解.如果这些进程全部是跑在一台机上的

七、变量与常量的简单介绍

七.变量与常量的简单介绍 本文将介绍VB语言中的变量与常量. 基本概念 首先大家要明白变量和常量是很重要的东西,因为他们储存着程序运行中的各种数据.顾名思义,变量就是可以变的量,而常量就是不变的,这个概念和数学上的有点接近. 接下来我简单讲讲这两个重要的东西:计算机程序在不运行的时候,程序文件保存在硬盘上,当用户运行程序之后,系统就会把程序文件装进计算机的内存里面,无论在硬盘中还是内存中,程序数据都是以二进制的形式保存着的.当程序在运行的时候,可以把计算机的内存理解为一个超级大的棋盘,每个格子都

TensorFlow简单介绍和在centos上的安装

##tensorflow简单介绍: TensorFlow? is an open source software library for numerical computation using data flow graphs.https://www.tensorflow.org/TensorFlow是谷歌基于DistBelief进行研发的第二代人工智能学习系统,其命名来源于本身的运行原理.Tensor(张量)意味着N维数组,Flow(流)意味着基于数据流图的计算,TensorFlow为张量从图