C++ 拷贝构造函数、拷贝赋值运算符、析构函数
每一次都会忘,做个笔记吧。想到哪里写到哪里。
拷贝构造函数
第一个参数必须是自身类类型的引用,且任何额外参数都有默认值。(为什么必须是引用?见后解释)
合成拷贝构造函数:如果我们没有为一个类定义拷贝构造函数,则编译器会为我们定义一个。同合成的默认构造函数不同的是,即使我们定义了其他构造函数,编译器也会为我们合成一个拷贝构造函数。(一旦自己定义了构造函数,则不会合成默认构造函数)
拷贝初始化与直接初始化
- 直接初始化:要求编译器使用普通的函数匹配来选择与我们提供的参数最匹配的构造函数。
- 拷贝初始化:要求编译器将右侧运算对象拷贝到正在创建的对象中,如果需要的话,还要进行类型转换。
string dots(10, '.'); //直接初始化
string s(dots); //直接初始化
string s2 = dots; //拷贝初始化
string null_book = "9-999-8999"; //拷贝初始化
string nines = string(100, '9'); //拷贝初始化
使用‘=’号的是拷贝初始化,不使用等号的是直接初始化。
拷贝初始化发生在以下情况
1. 用 = 定义变量时发生。
2. 将一个对象作为实参传递给一个非引用类型的形参。
3. 从一个返回类型为非引用类型的函数返回一个对象。
4. 用花括号列表初始化一个数组中的元素或一个聚合类中的成员。(聚合类是指没有用户定义的构造函数,没有私有和保护的非静态数据成员,没有基类,没有虚函数)。
拷贝构造函数第一个参数必须是引用原因:由于拷贝构造函数被用来初始化非引用类类型的参数。如果其自身参数不是引用类型,则调用永远也不会成功——为了调用拷贝构造函数,我们必须拷贝它的实参,但为了拷贝实参,我们又必须调用拷贝构造函数,如此无限循环。
拷贝赋值运算符
- 与类控制其对象如何初始化一样,类也可以控制器对象如何赋值:
Sales_data trans, accum;
trans = accum; //使用Sales_data的拷贝赋值运算符
与拷贝构造函数一样,如果类未定义自己的拷贝赋值运算符,编译器也会为它合成一个。
- 重载赋值运算符
- 重载运算符本质上是函数,其名字由operator关键字后接表示要定义的运算符的符号组成。因此,赋值运算符就是一个名为operator=的函数。类似于任何其他函数,运算符函数也有一个返回类型和一个参数列表。
- 如果是一个运算符是一个成员函数,其左侧运算对象就绑定到隐式的this参数。对于一个二元运算符,例如赋值运算符,其右侧运算对象作为显式参数传递。
- 拷贝赋值运算符接受一个与其类相同类型的参数:
class Foo{
public:
Foo& operator=(const Foo&); //赋值运算符
//...
};
为了与内置类型的赋值保持一致,赋值运算符通常返回一个指向其左侧运算对象的引用。注意,标准库通常要求保存在容器中的类型要有其赋值运算符,且其返回值是左侧运算对象的引用。
析构函数
析构函是类的一个成员函数,名字由波浪号接类名构成。它没有返回值,也不接受参数:
class Foo{
public:
~Foo(); //析构函数
//...
};
由于析构函数不接受参数,因此它不能被重载。对于一个给定类,只会由唯一一个析构函数。
在一个构造函数中,成员的初始化时在函数体执行之前完成的,且按照它们在类中出现的顺序进行初始化。在一个析构函数中,首先执行函数体,然后销毁成员。成员按初始化顺序的逆序进行销毁。
无论何时一个对象被销毁,就会自动调用其析构函数:
1. 变量在离开其作用域时被销毁
2. 当一个对象被销毁时,其成员被销毁
3. 容器(无论是标准容器还是数组)被销毁时,其元素被销毁
4. 对于动态分配的对象,当对指向它的指针应用delete运算符时被销毁
5. 对于临时对象,当创建它的完整表达式结束时被销毁
C++ 拷贝构造函数、拷贝赋值运算符、析构函数的更多相关文章
- C++的转换构造函数、拷贝构造函数、赋值运算符重载
1 转换构造函数 C++的转换构造函数是只有一个参数的构造函数.当程序试图将一个其他类型的对象或基本类型值赋给该类的一个待初始化对象时(如Person p="Dean";) ...
- C++ 构造函数、拷贝构造函数、赋值运算符
<C++ Primer Plus> 12.1 动态内存和类 12.1.1 复习示例和静态类成员 不能在类声明中初始化静态成员变量,这是因为声明描述了如何分配内存,但并不分配内存 如果在头文 ...
- C++ 拷贝构造函数和赋值运算符
本文主要介绍了拷贝构造函数和赋值运算符的区别,以及在什么时候调用拷贝构造函数.什么情况下调用赋值运算符.最后,简单的分析了下深拷贝和浅拷贝的问题. 拷贝构造函数和赋值运算符 在默认情况下(用户没有定义 ...
- C++禁止使用拷贝构造函数和赋值运算符方法
1.将拷贝构造函数和赋值运算符声明为私有,并不予实现 class Uncopyable { private: Uncopyable(const Uncopyable &); // 阻止copy ...
- [c++基础]3/5原则--拷贝构造函数+拷贝赋值操作符
/* * main.cpp * * Created on: Apr 7, 2016 * Author: lizhen */ #include <iostream> #include &qu ...
- 【C++ Primer 第15章】定义派生类拷贝构造函数、赋值运算符
学习资料 • 派生类的赋值运算符/赋值构造函数也必须处理它的基类成员的赋值 • C++ 基类构造函数带参数的继承方式及派生类的初始化 定义拷贝构造函数 [注意]对派生类进行拷贝构造时,如果想让基类的成 ...
- 拷贝构造函数 & 拷贝赋值运算符
一.拷贝构造函数 1. 形式 class A { public: // ... A(const A &); // 拷贝构造函数 }; 2. 合成拷贝构造函数 编译器总会为我们合成一个拷贝构造函 ...
- C++ 一个例子彻底搞清楚拷贝构造函数和赋值运算符重载的区别
class TestChild { public: TestChild() { x=; y=; printf("TestChild: Constructor be called!\n&quo ...
- C++ Primer 学习笔记_54_类和数据抽象 --拷贝构造函数、赋值运算符
拷贝控制 --复制构造函数.赋值操作符 引言: 当定义一个新类型时,须要显式或隐式地指定复制.赋值和撤销该类型的对象时会发生什么– 复制构造函数.赋值操作符和析构函数的作用! 复制构造函数: ...
- C++ 构造函数、析构函数、拷贝构造、赋值运算符
之所以要把它们放在一起,是因为在使用C/C++类语言的时候,很容易混淆这几个概念(对Java来说完全没有这样的问题,表示Javaor完全没有压力). 先建立一个测试类(包含.h和.cpp) //~ P ...
随机推荐
- (转)JAVA的整型与字符串相互转换
JAVA的整型与字符串相互转换1如何将字串 String 转换成整数 int? A. 有两个方法: 1). int i = Integer.parseInt([String]); 或 ...
- Java IO流学习总结八:Commons IO 2.5-IOUtils
Java IO流学习总结八:Commons IO 2.5-IOUtils 转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/550519 ...
- MongoDB学习总结(三) —— 常用聚合函数
上一篇介绍了MongoDB增删改查命令的基本用法,这一篇来学习一下MongoDB的一些基本聚合函数. 下面我们直奔主题,用简单的实例依次介绍一下. > count() 函数 集合的count函数 ...
- 关于C语言中变量类型转换
今天在工作中遇到一个问题,而在解决问题的过程中,发现一段关于int 型变量(a)和char型(b)变量间类型转换的代码存在问题:一个值为255的int型变量a,强制类型转换并赋值给char型变量b后, ...
- p1144一元三次方程求解
题目描述: 有形如:f(x)=ax^3+bx^2+cx+d=0这样的一元三次方程,给出该方程中各项的系数a,b,c,d,它们均为实数,并约定该方程一定存在着3个不同的实数解,解的范围在-100至100 ...
- 蔡勒(Zeller)公式:根据日期推算是星期几
Zeller's Congruence: w=y + [y/4] + [c/4] - 2c + [26(m+1)/10] + d - 1 公式中的符号含义如下:w:星期: w对7取模得:0-星期日,1 ...
- shell 获取指定目录下文件名
有两个目录a.b,两个文件夹目录里有一些文件的文件名是一样,不过后缀名不同,我想把a文件夹下跟b文件夹里相同文件名的文件覆盖到b去,并删除b里同名而不同后缀的文件,文件很多 #!/bin/bas ...
- 业务逻辑 : forex & mlm
业务逻辑 公司通过mlm的制度和顾客进行签约来收取资金,再把资金给第三方公司进行投资,再把所投资的回报给分配给公司和顾客. 公司的资金来自投资者,公司的营销策略来自mlm的制度,由市场人员来创建mlm ...
- JavaWeb从0开始学(一)-----搭建第一个Web应用程序与JSP工作原理
以往学习的时候大多是看完书或者看完视频,动手实践一下就OK了.然而过了一段时间我发现东西都忘差不多了,需要复习才能重新掌握.现在开始学习JavaWeb了,我将在这里记录自己的学习的一点一滴,不仅便于自 ...
- TypeScript设计模式之备忘录、命令
看看用TypeScript怎样实现常见的设计模式,顺便复习一下. 学模式最重要的不是记UML,而是知道什么模式可以解决什么样的问题,在做项目时碰到问题可以想到用哪个模式可以解决,UML忘了可以查,思想 ...