[笔记]C++拷贝构造和移动构造
一、拷贝构造
如果一个构造函数的第一个参数是自身类类型的引用,且任何额外参数都没有默认值,则此构造函数是拷贝构造函数。(《C++Primer,第五版》)
class Foo
{
public :
Foo();
Foo(const Foo&); //拷贝构造函数
Foo& operator=(const Foo&); //拷贝赋值运算符
};
类的成员中有指针时,使用深拷贝。
#include <iostream>
using namespace std; class Foo
{
public:
Foo()
{
pInt = new int;
*pInt = ;
}
Foo(const Foo&)= default; //拷贝构造函数
Foo& operator=(const Foo&) = default; //拷贝赋值运算符 int* pInt;
}; //浅拷贝,foo1和foo2中的pInt指向同一块内存地址
Foo foo1;
Foo foo2(foo1); //深拷贝
class Cop
{
public:
Cop()
{
pInt = new int;
*pInt = ;
}
Cop(const Cop& cop)
{
pInt = new int;
*pInt = *(cop.pInt);
}
int* pInt;
};
//深拷贝,cop1和cop2中pInt指向不同内存
Cop cop1;
Cop cop2(cop1);
二、移动构造
在某些情况下(函数返回对象引用),对象拷贝后立即就被消耗了。拷贝构造就回造成性能上的浪费,而且深拷贝也会造成浪费。移动构造可以避免这种情况的发生。
为了支持移动构造,C++11引入了右值引用。
右值引用:必须绑定到右值的引用,通过&&来获得右值引用,类似左值引用(常规引用),右值应用也是一块内存的别名。
右值:字面常量、在表达式求值过程中临时创建的对象,这些使用过后就被销毁的资源。不同于左值的持久状态。
因此,右值引用只能绑定到将要被销毁的对象上,左值引用只能绑定到持久的对象上。
//例子来源于 《C++primer 第五版》 int i = ;
int& r = i; //正确,i是左值
int&& rr = i; //错误
int& r2 = i * ; //错误,i*42是右值,用完即销毁
const int& r3 = i * ; //正确,隐式转换为左值后,r3引用
int&& rr2 = i * ; //正确,绑定右值
int&& rr1 = 42; //正确,字面常量是右值
int&& rr2 = rr1; //错误,rr1左值
变量都是左值,因此无法将右值引用绑定到一个右值引用类型的变量上。
如果要将右值引用绑定到左值上,可以通过move函数来获得左值的右值引用类型。对一个左值调用move函数后,除了对该左值赋值和销毁外,不再使用它。
int i = ;
int&& rr = move(i); //i和rr引用同一块内存 i = ; cout << i << endl;
cout << rr << endl;
移动构造函数依靠右值引用特性来将来改变内存的管理者,而不同于拷贝构造对内存进行拷贝。
移动构造:第一个参数是该类类型的一个右值引用,且任何额外的参数都必须有默认实参。使用移动构造函数必须确保销毁移后源对象是无害的(不会重复释放同一块内存)。
Cop(Cop&& cop) noexcept : pInt(cop.pInt)
{
cout << "this is &&" << endl;
cop.pInt = NULL;
}
Cop& operator=(Cop&& cop) noexcept
{
if ( this == &cop ) return *this;
cout << "this is && =" << endl;
delete pInt;
pInt = cop.pInt;
cop.pInt = NULL; } Cop retCop()
{
Cop cop3;
*cop3.pInt = ;
return cop3;
} //调用移动赋值运算符,cop3中pInt接管retCop返回对象中的pInt指向内存
Cop cop3 = retCop();
noexcept承诺函数不抛出异常,标准库对这个函数不做额外处理。
[笔记]C++拷贝构造和移动构造的更多相关文章
- Effective C++_笔记_条款09_绝不在构造和析构过程中调用virtual函数
(整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 为方便采用书上的例子,先提出问题,在说解决方案. 1 问题 1: ...
- C++ 构造中调用构造
//构造中调用构造 #define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; class Point{ ...
- 《Effective C++》读书笔记 被你忽略的关于构造析构赋值
如果程序员没有定义,那么编译器会默认隐式为你创建一个copy构造函数,一个copy赋值操作符,一个析构函数.另外如果你没有声明任何构造函数,编译器会为你声明一个default构造函数. 但是只有当这些 ...
- C++深度解析教程学习笔记(6)对象的构造和销毁
1. 对象的初始化 (1)从程序设计的角度看,对象只是变量,因此: ①在栈上创建对象时,成员变量初始化为随机值 ②在堆上创建对象时,成员变量初始化为随机值 ③在静态存储区创建对象时,成员变量初始化为 ...
- C#线程学习笔记五:线程同步--事件构造
本笔记摘抄自:https://www.cnblogs.com/zhili/archive/2012/07/23/Event_Constructor.html,记录一下学习过程以备后续查用. 前面讲的线 ...
- STL——容器(Set & multiset)的默认构造 & 带参构造 & 对象的拷贝构造与赋值
1. 默认构造 set<int> setInt; //一个存放int的set容器. set<float> setFloat; //一 ...
- C++ 笔记(二) —— 不要在构造和析构函数中调用虚函数
ilocker:关注 Android 安全(新手) QQ: 2597294287 class Transaction { //所有交易的 base class public: Transaction( ...
- [DeeplearningAI笔记]卷积神经网络1.6-1.7构造多通道卷积神经网络
4.1卷积神经网络 觉得有用的话,欢迎一起讨论相互学习~Follow Me 1.6多通道卷积 原理 对于一个多通道的卷积操作,可以将卷积核设置为一个立方体,则其从左上角开始向右移动然后向下移动,这里设 ...
- JavaScript模式读书笔记 文章3章 文字和构造
1.对象字面量 -1.Javascript中所创建的自己定义对象在任务时候都是可变的.能够从一个空对象開始,依据须要添加函数.对象字面量模式能够使我们在创建对象的时候向其加入函数. ...
随机推荐
- Guide 哥:有哪些程序员受用一生的好习惯?
本文来自 Guide 哥开源的 Github 仓库 programmer-advancement:https://github.com/Snailclimb/programmer-advancemen ...
- SPOJ-MobileService--线性DP
题目链接 https://www.luogu.org/problemnew/show/SP703 方法一 分析 很显然可以用一个四维的状态\(f[n][a][b][c]\)表示完成第i个任务时且三人 ...
- # 机器学习算法总结-第五天(降维算法PCA/SVD)
- 使用Leangoo玩转故事地图
转自:https://www.leangoo.com/9944.html 用户故事是在敏捷开发中表达需求的主要方式,我们在做敏捷开发的时候都有需求池的概念,在Scrum中这个需求池就是产品backlo ...
- Python入门之第三方模块安装
Python入门之第三方模块安装 平台:Win10 x64 + Anaconda3-5.3.0 (+Python3.7.0) Issue说明:pip install line_profiler-2.1 ...
- Java中Static关键字详解以及静态变量和成员变量的区别
一.static关键字的特点 (1)修饰成员变量.成员方法(2)随着类的加载而加载(3)优先于对象存在(4)被所有对象共享(5)可以通过类名调用 它本身也可以通过对象名调用 例如:main()方法由j ...
- Linux的bg和fg命令
我们都知道,在 Windows 上面,我们要么让一个程序作为服务在后台一直运行,要么停止这个服务.而不能让程序在前台后台之间切换.而 Linux 提供了 fg 和 bg 命令,让我们轻松调度正在运行的 ...
- Django_01_创建图书管理项目
在django中,项目的组织结构为一个项目包含多个应用,一个应用对应一个业务模块 示例:创建项目的名称为test1,完成“图书-英雄”信息的维护,创建应用名称为booktest 创建项目:首先进入到虚 ...
- 两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?(未完成)
两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?(未完成)
- 挺棒的七个Python图形应用GUI开发框架
作为Pyhon开发者,你迟早都会碰到图形用户界面(GUI)应用开发任务,目前市场上有大量Python GUI开发框架可供选择,Python wiki GUI programming给出了超过30个跨平 ...