C++复制控制:赋值操作符和析构函数
一、赋值操作符
类定义了该类型对象赋值时会发生什么。与拷贝构造函数一样,如果类没有定义自己的赋值操作符,编译器会合成一个。
1、重载操作符的简单介绍
重载操作符是一些函数,其名字为operator后跟着所定义的操作符的符号,通过定义名为operator=的函数,我们可以对赋值进行定义。操作符函数的形参表必须具有与该操作数数目相同的形参(如果操作符是一个成员,则包括隐式this形参)。赋值是二元操作符,对应的两个形参,第一个形参为左操作数,第二个形参为右操作数。
注意:
(1)当操作符为成员函数时,它的第一个操作数隐式绑定到this指针。
(2)有些操作符,例如赋值操作符必须定义为成员函数,因此赋值操作符可接受单个形参。
(3)赋值操作符返回对右操作数的引用。
2、合成赋值操作符
合成赋值操作符会执行逐个成员赋值:右操作数对象的每个成员赋值为左操作数对象的对应成员。对于数组,给每个数组元素赋值。
Sales_item& Sales_item::Sales_item(const Sales_item &rhs)
{
isbn = rhs.isbn;
units_sold = rhs.units_sold;
revenue = rhs.revenue;
return *this; //返回对左操作数的引用
}
3、拷贝和赋值常一起使用
可以使用拷贝构造函数的类通常也可使用合成赋值操作符。一般而言,如果类需要拷贝构造函数,它也会需要赋值操作符。应将两者看作一个单元,如果需要其中一个,我们几乎也肯定需要另一个。
二、析构函数
析构函数的作用是完成所需资源的回收,作为类构造函数的补充。
1、何时调用析构函数
撤销类对象时自动调用析构函数:
(1)变量在超出作用域时自动撤销。例如:变量item遇到右}时。
(2)动态分配的对象只有在指向该对象的指针被删除时才撤销。例如:指针p。
Sales_item *p = new Sales_item;
{
Sales_item item(*p);
delete p;
}
注意:当对象的引用或指针超出作用域时,不会运行析构函数。只有删除指向动态分配对象的指针或实际对象(而不是对象的引用)超出作用域时,才会运行析构函数。
(3)撤销一个容器(不管是标准库还是内置数组)也会运行容器中元素的析构函数。
容器中的元素总是按逆序撤销,首先撤销下标为size()-1的元素,最后撤销下标为0的元素。
{
Sales_item *p = new Sales_item[];
vector<Sales_item> vec(p, p + );
delete [] p;
}
2、何时编写显式析构函数
许多类不需要显式析构函数,具有构造函数的类不一定需要定义自己的析构函数,仅在有些工作需要析构函数完成时,才需要析构函数。析构函数通常用于释放在构造函数或在对象生命期内获取的资源。
注意:
(1)如果类需要析构函数,则它也需要赋值操作符和拷贝构造函数,这是一个有用的经验法则。
(2)析构函数并不仅限于用来释放资源。一般而言,析构函数可以执行任意操作,该操作是类设计者希望在该类对象的使用完毕之后执行的。
3、合成析构函数
与拷贝构造函数和赋值操作符不同,编译器总会为我们合成一个析构函数。合成析构函数按对象创建时的逆序撤销每个非static成员,按成员在类中声明的逆序撤销成员。对于类类型的每个成员,合成析构函数调用该成员的析构函数撤销对象。
注意:撤销内置类型成员或复合类型成员没什么影响,合成析构函数并不删除指针成员做指向的对象。
4、编写析构函数
析构函数的名字前加~,没有返回值,没有形参(所以不能重载析构函数)。
注意:
(1)类可以定义多个构造函数,但只能提供一个析构函数,应用于类的所有对象。
(2)析构函数区别于拷贝构造函数和赋值操作符,即使定义了自己的析构函数,合成析构函数仍然运行。
class Sales_item
{
public:
~Sales_item(){}
private:
string isbn;
int units_sold;
double revenue;
};
撤销Sales_item对象时,首先运行这个什么都不做的析构函数,然后再运行合成析构函数撤销类的成员。
C++复制控制:赋值操作符和析构函数的更多相关文章
- C++11六大函数(构造函数,移动构造函数,移动赋值操作符,复制构造函数,赋值操作符,析构函数)
在C++中,有三大函数复制控制(复制构造函数,赋值操作符,析构函数),而在C++11中,加入了移动构造函数,移动赋值操作符.我就斗胆将他们命名为六大函数好了. 一.构造函数 c++primer中说过: ...
- C++在单继承、多继承、虚继承时,构造函数、复制构造函数、赋值操作符、析构函数的执行顺序和执行内容
一.本文目的与说明 1. 本文目的:理清在各种继承时,构造函数.复制构造函数.赋值操作符.析构函数的执行顺序和执行内容. 2. 说明:虽然复制构造函数属于构造函数的一种,有共同的地方,但是也具有一定的 ...
- 析构函数-复制构造函数-赋值操作符重载-默认构造函数<代码解析>
通过下面primer中的一道习题,可以更深刻的了解,析构函数,复制构造函数,赋值操作符重载,默认构造函数的使用. 但是我的结果与primer习题解答里面的并不相同,可能是编译器不同的原因导致. // ...
- 深入C++中构造函数、拷贝构造函数、赋值操作符、析构函数的调用过程总结
转自 http://www.jb51.net/article/37527.htm,感谢作者 #include "stdafx.h" #include <iostre ...
- 赋值操作符、复制构造函数、析构函数、static成员练习
/** * 定义一个Employee类,包含雇员名字和一个唯一的雇员标识,为该类定义默认构造函数和参数为表示 * 雇员名字的string构造函数.如果该类需要复制构造函数或赋值操作符,实现这些函数 * ...
- c++ 构造函数,拷贝构造函数,析构函数与赋值操作符
题目: 为下面的Rectangle类实现构造函数,拷贝构造函数,赋值操作符,析构函数. class Shape { int no; }; class Point { int x; int y; }; ...
- C++ 复制控制之复制构造函数
7月26日更新: 过了这么长的时间回过头来看,发现文章中有几个点说错(用红字标出): 构造函数不是只有唯一一个参数,它也可以是多参数形式,其第二参数及后继以一个默认值供应. 不是没有声明复制控制函数时 ...
- C++ Primer 随笔 Chapter 13 复制控制
1.复制控制包含的内容:复制构造函数.赋值操作符.析构函数 2.复制构造函数: a. 定义:只有单个形参,而且该形参是对本类类型的引用,这样的构造函数被成为复制构造函数 b. 适用情况: (1)根据一 ...
- 稍微深入点理解C++复制控制【转】
通过一个实例稍微深入理解C++复制控制过程,参考资料<C++ primer>,介绍点基本知识: 1.在C++中类通过特殊的成员函数:复制构造函数.赋值操作符和析构函数来控制复制.赋值和撤销 ...
随机推荐
- ABP官方文档翻译 1.4 启动配置
启动配置 配置ABP 替换内置服务 配置模块 创建模块配置 ABP提供了基础设施和模型在启动的时候对它及模块进行配置. 配置ABP 在模块的PreInitialize事件中配置ABP.示例配置如下: ...
- Promise原理剖析
传统的异步回调编程最大的缺陷是:回调地狱,由于业务逻辑非常复杂,代码串行请求好几层:并行请求以前也要通过引用step.async库实现.现在ES6推出了Promise,通过Promise的链式调用可以 ...
- 在MySQL中使用explain查询SQL的执行计划
1.什么是MySQL执行计划 要对执行计划有个比较好的理解,需要先对MySQL的基础结构及查询基本原理有简单的了解. MySQL本身的功能架构分为三个部分,分别是 应用层.逻辑层.物理层,不只是MyS ...
- go基础语法
定义变量: 可放在函数内,或直接放在包内使用var集中定义变量使用:=定义变量写的短一些 package main import ( "fmt" "math" ...
- 使用vs的时候,遇到这个:当前不会命中断点 还没有为该文档加载任何符号
一 http://stackoverflow.com/questions/2155930/fixing-the-breakpoint-will-not-currently-be-hit-no-symb ...
- sphinx 安装使用
一.linux(centos)下安装源码包 1.下载 wget http://sphinxsearch.com/files/sphinx-2.3.1-beta.tar.gz 2.安装 切换目录到 ...
- CDN专业一站式解决方案
调度,弱网加速,动态防御,无限节点(重)新技术
- 面试代码基础(一)从strstr说起
对于写程序要注意:要能在面试官的提示下把代码写出来(把思想实现的能力)!还要注意边界检查!递归找到出口! 开场来个简单字符串匹配 int strstr(char* target,char* sourc ...
- Python基础笔记系列九:变量、自定义函数以及局部变量和全局变量
本系列教程供个人学习笔记使用,如果您要浏览可能需要其它编程语言基础(如C语言),why?因为我写得烂啊,只有我自己看得懂!! 变量在前面的系列中也许就可以发现,python中的变量和C中的变量有些许不 ...
- Java线程池可用的队列
Java线程池ThreadPoolExecutor的构造器: public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long ...