C++movesemantic移动语义介绍

目录

前言

移动构造

为什么我们需要move semantic

前言

在说移动语义之前 本文作者假设你已经具备了深拷贝浅拷贝左值右值等基本概念 本文不会再过多叙述 那么接下来 让我们开始吧

Tips:(警告 警告 警告 警告)在阅读本文章之前 作者首先提醒 线代编译器有RVO和NRVO等一系列优化策略 除非你明确知道你要使用std::move 不然我并不是很推荐你使用移动语义 他很有可能是无意义的

移动构造

在说移动语义之前 让我们先来说说移动构造这玩意

我们都知道 深拷贝是会把在堆区的内存一起拷贝的 那么如果我们明确知道一个对象并不会再继续使用 但是同时我们又想拿到他堆区的资源的时候 我们应该怎么办呢? 移动构造给我们提供了这种能力 代码如下所示:

class MoveClass { public: int* p; MoveClass() { p = new int(); std::cout << "默认构造调用" << std::endl; } ~MoveClass() { std::cout << "析构函数调用" << std::endl; if (!p) delete p; } MoveClass(MoveClass& tmp) { } MoveClass(MoveClass&& tmp) { std::cout << "移动构造函数调用" << std::endl; this->p = tmp.p; tmp.p = nullptr; } MoveClass& operator=(MoveClass&& tmp) { std::cout << "移动构造函数调用" << std::endl; this->p = tmp.p; tmp.p = nullptr; } }; MoveClass MoveClassTest(MoveClass d) { return MoveClass(); } int main() { MoveClass cc; //好 接下来我们不再想使用c了 但是堆区的资源我们并不想拷贝 那么使用如下构造方式 MoveClass d(std::move(cc)); system("pause"); }

移动前数据如下图所示:

移动后数据如下图所示:

程序输出结果:

为什么我们需要move semantic

设想一个场景 我们在一个作用域申请了一个超级大的string 如下图所示

#include <iostream> #include <string.h> void test1(std::string s) { std::cout << "test1:" << s.c_str()<<std::endl;; } void test() { std::string s = "超级大的string"; test1(s); std::cout <<"test:"<< s.c_str() << std::endl; return; } int main() { test(); system("pause"); }

运行结果如下:

你们就要说了 有啥用啊 但是只要你懂一点c++ 你就会知道 在test中的s我们是不需要了的 也就是我们在test是不想再继续使用s的 但是在我们调用test1的时候 我们又重新拷贝了s一份 那么性能是不是就浪费了呢?如果这个string超级大 你的程序是不是就很垃呢

我们只需要简简单单的加一个std::move 他就不是拷贝 而只是单纯的移动指针 如下

#include <iostream> #include <string.h> void test1(std::string s) { std::cout << "test1:" << s.c_str()<<std::endl;; } void test() { std::string s = "超级大的string"; test1(std::move(s)); std::cout <<"test:"<< s.c_str() << std::endl; return; } int main() { test(); system("pause"); }

运行结果如下:

这就是他最最最本质的作用 一个东西是左值时 你仍然想要他去触发移动构造记住 其他时候你并不需要去考虑 因为编译器有优化懂吗 不要尝试自己去干扰编译器的优化 除非你真的非常非常非常清楚你自己正在干什么

到此这篇关于C++ move semantic移动语义介绍的文章就介绍到这了,更多相关C++ move semantic内容请搜索易知道(ezd.cc)以前的文章或继续浏览下面的相关文章希望大家以后多多支持易知道(ezd.cc)!

推荐阅读

    C++超详细讲解模板的使用

    C&#43;&#43;超详细讲解模板的使用目录一、函数模板1.1函数模板概念1.2 函数模板格式1.3 函数模板的原理1.4 函数模板的实例化二、类模板

    C++学习之多态的使用详解

    C&#43;&#43;学习之多态的使用详解目录前言多态向上转型向下转型作用域前言
    最近为了完成数据库系统的实验,又复习起了《C&#43;&#43; Prim

    c++实现md5加密的代码

    c&#43;&#43;实现md5加密的代码最近发现md5加密算法挺有趣,特点是单向加密不可逆,加密后的字符串长度相等,于是就用C&#43;&#43;尝试实现了一

    C++实现优先队列的示例详解

    C&#43;&#43;实现优先队列的示例详解目录前言堆的存储方式维护堆的方法1、上浮操作2、下沉操作附上代码前言
    首先,啊,先简单介绍一下优先队

    C++实现简易通讯录功能

    C&#43;&#43;实现简易通讯录功能目录实现功能一、定义通讯录和通讯录人员结构体二、实现通讯录输入菜单1.定义菜单函数:2.主函数循环体中

    C++实现通讯录系统项目实战

    C&#43;&#43;实现通讯录系统项目实战本文实例为大家分享了C&#43;&#43;实现通讯录系统项目的具体代码,供大家参考,具体内容如下
    制作一个具

    C++实现通讯录小功能

    C&#43;&#43;实现通讯录小功能本文实例为大家分享了C&#43;&#43;实现通讯录功能的具体代码,供大家参考,具体内容如下
    思路:
    1.显示菜单栏
    voi

    C++实现简易通讯录管理系统

    C&#43;&#43;实现简易通讯录管理系统目录前言结构体联系人结构体通讯录结构体函数模块菜单添加联系人显示联系人判断联系人删除联系人查

    C++实现通讯录管理系统项目

    C&#43;&#43;实现通讯录管理系统项目本文实例为大家分享了C&#43;&#43;实现通讯录管理系统的具体代码,供大家参考,具体内容如下
    1、通讯录设