首页 > 编程语言 >C++移动构造与std::move()

C++移动构造与std::move()

时间:2023-12-19 12:12:29浏览次数:33  
标签:std string move C++ Entity 构造 MyString data size

背景及问题

如下程序所示:
#include<iostream>

class MyString {
public:
	MyString() = default;
	MyString(const char* data)
	{		
		printf("%s", "MyString Constructed!!\n");
		size = strlen(data);
		m_data = new char[size];
		memcpy(m_data, data, size);	
	}
	~MyString()
	{
		if (m_data)
		{
			printf("%s", "MyString Destroyed!!\n");
			delete m_data;
		}	
	}
	//copy constructor
	MyString(const MyString& other) noexcept
	{
		printf("%s", "MyString Copyed!!\n");
		size = other.size;
		m_data = new char[size];
		memcpy(m_data, other.m_data, size);
	}

private:
	char* m_data;
	int size;
};

class Entity
{
public:
	//constructor
	Entity(const MyString& string):m_string(string) {}
private:
	MyString m_string;
};

int main()
{	

	Entity entity("Hello");
	return 0;
}

程序说明

程序定义了一个MyString类,其中构造函数和拷贝构造函数需要对传进来的字符串开辟空间并复制内容,另外一个Entity类含有一个MyString成员,并在初始化时复制传入的MyString对象。主程序Main中以常量字符串构造一个entity示例。

image

运行程序会发现,MyString构造了一次,拷贝一次,程序结束析构两次,符合运行逻辑。“Hello”字符串先通过构造函数构造一个临时变量MyString,临时变量再通过Entity内的构造函数拷贝构造给成员变量m_string

问题在于临时变量拷贝构造需要重新开辟空间,并且“用完即扔”,为什么不直接将“hello”构造好的MyString直接“移动”到Entity?这样会节省空间,提高效率。用此引出移动构造和std::move()

移动构造与std::move()

若要实现将临时变量移动到Entity,首先MyString要加入移动构造,如下:
	MyString(MyString&& other) noexcept
	{
		printf("%s", "MyString Moved!!\n");
		size = other.size;
		m_data = other.m_data;

		//clear origin data
		other.size = 0;
		other.m_data = nullptr;
	}

此为移动构造,接受的是一个右值,构造是直接复制原MyString的size与data,不重新开辟空间做深拷贝。并将原MyString清零。接着对Entity构造时使用std::move通知移动构造函数,如下:

	Entity(MyString&& string) :m_string(std::move(string)) {}

image

需要注意的是

1. Entity右值构造时也可不使用std::move,直接将参数强转为右值类型也可以,std::move相当于通知构造函数以移动构造的方式进行
Entity(MyString&& string) :m_string((MyString&&)string) {}

2. 对于形参为Const YourType &类型的既可以接受左值,也可以接受右值。但是使用std::move会编译错误,因为Const值不能被移动,所以Entity构造仍要单独写一个右值构造

3. MyString移动构造时,复制了临时数据的值还要对其清空,因为数据已经被移动,指针没有置空,析构两次会引起Crash问题

标签:std,string,move,C++,Entity,构造,MyString,data,size
From: https://www.cnblogs.com/stephen2023/p/17913415.html

相关文章

  • C++ 反向遍历 array 小记
    有时候需要逆向循环,例如从字符串的最右端遍历到最左端,需要注意一些细节!初学遇到一些bug记录在这里。首先arr.size()的数据类型为size_t,为无符号整型对于for(intidx=arr.size()-1;idx>=0;idx--):使用int作为idx的类型,有一定概率会编译失败,因为size_t的具......
  • C++U4-第09课-STL容器
    学习目标 STL  栈stack [入栈出栈] 【算法分析】栈的基本操作。【参考代码】#include<bits/stdc++.h>usingnamespacestd;intmain(){stack<int>st;intn;cin>>n;for(inti=1;i<=n;i++){intx;cin......
  • 【面试官版】【持续更新中】融合滤波算法+数据结构+激光视觉SLAM+C++面试题汇总
    C++部分什么时候需要写虚函数、什么时候需要写纯虚函数?只继承接口为纯虚函数强调覆盖父类重写,或者父类也需要实现一定的功能,为虚函数指针传参和引用传参区别?引用传参本质上是传递原参数地址,指针传参本质还是值传递,生成拷贝指针,拷贝指针和原指针指向的为同一块内存。因此改变......
  • 【我们尽量少说废话的讲完】C++红黑树原理
    红黑树的出现红黑树增删改查的时间复杂度都是O(logn)。如果插入的数据随机,那么使用二叉搜索树即可保证树接近平衡。此时增删改查的效率都为O(logN)。但如果插入的数据为有序的,此时二叉搜索树极其不平衡,退化为链表,时间复杂度降为O(N)。而红黑树就是为了应对这种极端情况。红黑......
  • 【纯代码复制粘贴即可使用】卡尔曼滤波的C++实现
    使用Eigen实现卡尔曼滤波。如果实现扩展卡尔曼滤波只需将H矩阵换成雅可比的求解。#ifndef_MYKALMAN_H#define_MYKALMAN_H#include<Eigen\Dense>classKalmanFilter{public:KalmanFilter(intstateSize,intmeasSize,intuSize);~KalmanFilter()=default;......
  • C++ 获取 vector 最大的 3 个数字
    假设现在有一个数组存储了成绩信息,要获得前三名#include<iostream>#include<vector>#include<algorithm>std::vector<int>scores{10,30,90,30,100,20,10,0,30,40,40,70,70};下面这种方法可以将前3名成绩复制到结果里,同时考虑到scores长度小于3的情况。......
  • c++学习书籍
      C++ Primer 第五版 第四版 对比 差异C++Primer是一本经典的C++编程教材,它的第五版与第四版有哪些不同点呢?首先,C++Primer第五版引入了C++11标准,讲解了C++11的新特性,例如auto类型推导、lambda表达式、右值引用、智能指针等等。这些新特性有助于提高C++程序的性能......
  • centos升级nginx,增加fastdfs插件
    解决nginx漏洞,需要升级到指定1.22.1版本nginx缓冲区错误漏洞(CVE-2022-41741)nginx越界写入漏洞(CVE-2022-41742)https://mailman.nginx.org/pipermail/nginx-announce/2022/RBRRON6PYBJJM2XIAPQBFBVLR4Q6IHRA.html升级:首先到安装目录下cd/usr/local/nginx1、首先下载......
  • C++ Qt开发:TableWidget表格组件
    Qt是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍TableWidget表格组件的常用方法及灵活运用。QTableWidget是Qt中用于显示表格数据的部件。它是......
  • C++ Qt开发:MdiArea多窗体组件
    Qt是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍MdiArea`组件的常用方法及灵活运用。QMdiArea(MultipleDocumentInterfaceArea)是Qt中用于创建多......