Big Three

C++ 中Big Three指的是copy ctor 和 copy op=  和  dtor

m_data是个字符串指针。一般而言,处理字符串,都是使用指针,在需要存储字符的时候再创建内存,这是因为字符串的长度有大有小,指针的处理方式有种动态的感觉。使用数组的话,则无法准确设置字符串大小。

默认情况下,如果不写Big Three的话,compiler会帮助我们构造一个。对于copy ctor 、copy op= 其默认行为是逐bit去copy。对于dtor,其默认行为是private data逐bit删除。既然compiler针对Big Three已经提供了一套实现,我们还有必要去写吗?回答这个问题,我们先要弄清楚compiler默认给出的Big Three够不够用。对于Class without pointer member(s),往往compiler默认提供的那套Big Three就够了。但是对于Class with pointer member(s),使用compiler默认提供的那套Big Three往往会导致memory leaks

构造函数:ctor

字符串是什么,从C语言延续下来的概念:有个指针指向一个头,然后后面跟着一串,最后是'\0'结束符号。一个字符串多长,有2种想法

一种是,我不知道多长,但是最后有'\0'结束符号。

另外一种是,最后没有'\0'结束符号,但是有一个表示长度的整数。

拷贝构造函数:copy ctor

接受的是他自己这种东西

拷贝赋值函数:copy op=

接受的是他自己这种东西

compiler默认行为

compiler默认提供的copy ctor,其逐bit拷贝行为如下

默认行为带来两个问题:

①b=a后,b原本指向的memory就发生了内存泄漏。

②b和a指向一块memory,一个改动memory另一个也会跟着受影响。

copy op=的正确步骤一般是是:

①检查self copy

②taiget端原有数据清空

③target端分配和source端相同大小memory

④把source端内存copy到target端

为什么一定要检查self-copy

有两点原因

①浅层原因:都已经存在一份object了,自己拷贝自己还要执行上面copy op=的②~④,效率低下

②本质原因:问题的根本原因并不是效率上的损失那么简单。这可能导致程序行为的不确定性。

如果没有self copy检查,开始copy op=时如下

执行完②,在执行③时,计算source所占memory时行为是不确定的,即neimory具体大小是不确定的。导致后面为target分配内存行为也不确定。最终会导致程序执行情况的不确定。

析构函数:dtor

这段代码展示了ctor和dtor的用法。s1、s2是开辟function stack memory,系统可以自动回收。p开辟的是system heap memory,需要Programmer手动回收。在离开{ }时s1、s2会自动自动调用dtor回收memory。delete p的时候也会调用dtor回收memory。因此整段代码调用3次ctor,3次dtor。

程序执行析构函数的时机有以下4种。

  • 如果在函数中定义了一个对象,当这个函数调用结束时,对象会被释放,且在对象释放前会自动执行析构函数。
  • static局部对象在函数调用结束时对象不释放,所以也不执行析构函数,只有在main 函数结束或调用exit函数结束程序时,才调用static局部对象的析构函数。
  • 全局对象则是在程序流程离开其作用域(如main 函数结束或调用exit函数)时,才会执行该全局对象的析构函数。
  • 用new建立的对象,用delete释放该对象时,会调用该对象的析构函数。析构函数的作用不是删除对象,而是在撤销对象占用的内存前完成一些清理工作,使得放些内存可以供新对象使用。析构函数的作用也不限于释放资源方面,它还可以被用来执行用户希望在最后一次使用对象之后所执行的任何操作。

C++——Big Three(copy ctor、copy op=、dtor)的更多相关文章

  1. C++ 拷贝构造函数 copy ctor & 拷贝赋值函数 copy op=

    类中含有  指针类型  的成员变量时,就必须要定义 copy ctor 和 copy op= copy ctor 请见: class Rectangle { public: Rectangle(Rec ...

  2. Python基础—set、copy(Day7)

    一.数据类型补充 1.str:.isspace()字符串是空格或至少是一个空格. s='alex' s1=' ' ret=s1.isspace() print(ret)执行结果:True  2.tul ...

  3. python字典(dictionary)使用:基本函数code实例,字典的合并、排序、copy,函数中*args 和**kwargs做形参和实参

    python字典dictionary几个不常用函数例子 一.字典声明 如,d={}; d= {'x':1,'b':2} d1 = dict(x=1,y=2,z=3)     d2 = dict(a=3 ...

  4. iOS之NSArray类簇简介-(copy、mutableCopy导致程序crash)

    1.前言 开发时常常用数组对数据进行处理,对NSMutableArray进行操作时经常导致程序崩溃,特研究一下NSArray的类簇!涉及__NSPlaceholderArray.__NSArray0. ...

  5. C++异常安全、copy and swap

    异常安全的代码是指,满足两个条件 1异常中立性 : 是指当你的代码(包括你调用的代码)引发异常时,这个异常 能保持原样传递到外层调用代码.(异常中立,就是指任何底层的异常都会抛出到上层,也就相当于是异 ...

  6. 【iOS atomic、nonatomic、assign、copy、retain、weak、strong】的定义和区别详解

    一.atomic与nonatomic 1.相同点 都是为对象添加get和set方法 2.不同点 atomic为get方法加了一把安全锁(及原子锁),使得方法get线程安全,执行效率慢 nonatomi ...

  7. iOS中assign、copy 、retain等关键字的含义

    iOS中assign.copy .retain等关键字的含义  转自:http://my.oschina.net/majiage/blog/267409 assign: 简单赋值,不更改索引计数cop ...

  8. Objective-C中的Strong、Copy与MutableCopy

    面试过程中经常被问到ARC中Strong.Copy的区别是什么.普通的回答是:一样.文艺(正确)的回答是:分情况(我擦!WQY#$&Y**%OWEUR) 可以先参考这篇文章http://www ...

  9. OC:内存管理、dealloc方法、copy知识点

    属性的声明:使⽤@property声明属性
 例如:@property NSString *name: 相当于@interface中声明了两个⽅法(setter.getter): 属性的实现:使⽤@s ...

随机推荐

  1. Swift4.0复习循环

    1.for-in循环: 2.while循环: 3.repeat-while循环: repeat { // 循环体中的一条或多条执行语句 } while condition 4.标签语句: if_lab ...

  2. 【嵌入式硬件Esp32】Eclipse c++切换回英文方法

    1.英文版汉化为中文版时是通过:Help-Install New Soft,下载安装中文支持包,重启即可. 2.恢复回英文界面步骤则如下: 2.1.打开安装目录下的eclipse.ini,在文件文件中 ...

  3. 【转载】我为什么放弃了 Linux 内核学习?

    最近学习内核很是心累,碰巧看到这篇文章,有点意思~ 转自http://happypeter.github.io/index.html,以下为原文内容: 我在国内的技术类网站 / 博客上, 时常会看到分 ...

  4. 常见问题:Web/Servlet生命周期与Spring Bean生命周期

    Servlet生命周期 init()初始化阶段 Servlet容器加载Servlet(web.xml中有load-on-startup=1;Servlet容器启动后用户首次向Servlet发请求;Se ...

  5. Mysql sqlyog 错误1045

    首先打开运行窗口输入cmd进入DOS界面或者打开MySQL Workbench Step1: cd C:\Program Files\MySQL\MySQL Server 5.6\bin Step2: ...

  6. 软件素材---C/C++格式化显示当前时间--标准函数strftime

    函数原型:size_t strftime (char* ptr, size_t maxsize, const char* format,const struct tm* timeptr ); 头文件: ...

  7. kafka生产者消费者

    import org.apache.kafka.clients.consumer.ConsumerRecord; import org.apache.kafka.clients.consumer.Co ...

  8. C++程序的多文件组成

    C++程序的多文件组成 [例3.32] 一个源程序按照结构划分为3个文件 // 文件1 student.h (类的声明部分) #include<iostream.h> #include&l ...

  9. 第五章 模块之 getpass、sys、os

    5.5 getpass 密码不显示(只能在终端运行) 密码不显示(只能在终端运行) import getpass​pwd = getpass.getpass('请输入密码:')if pwd == '1 ...

  10. 07 UML类图

    移步: https://www.cnblogs.com/coolstream/p/9572846.html