C++ 已经拥有了拷贝构造函数, 和赋值函数,它们主要定位为浅和深度拷贝, 新增加一个移动构造函数,主要避免拷贝构造。

在定义了移动构造函数的情况下,在实参(argument)是一个右值(rvalue,包括xvalue和prvalue)的情况下会调用移动构造函数,而不是调用复制构造函数

可以使用std::move语句可以将左值变为右值而避免拷贝构造,修改代码如下:

编译器会对返回值进行优化,简称RVO,是编译器的一项优化技术,它涉及(功能是)消除为保存函数返回值而创建的临时对象。

-fno-elide-constructors,此选项作用是,在 g++ 上编译时关闭 RVO。

shell> g++ main.cpp -std=c++11 -fno-elide-constructors

#include <iostream>
using namespace std; class Test
{
public:
Test(int a = 0)
{
d = new int(a);
cout << "cs" << this <<endl;
} Test(const Test & tmp)
{
d = new int;
*d = *(tmp.d);
cout << "copy\n";
} // Test(Test && tmp)
// { // 移动构造函数
// d = tmp.d;
// tmp.d = NULL; // 将临时值的指针成员置空
// cout << "mv" << this << endl;
// } ~Test()
{
if(d != NULL)
{
delete d;
cout << "delete d\n";
}
cout << "ds: " << this << endl;
} int * d;
}; Test GetTmp()
{
Test h;
cout << "Resource from " << __func__ << ": " << (void *)h.d << endl;
return h;
} int main()
{
//Test&& obj = GetTmp();
Test obj = GetTmp();
cout << "Resource from " << __func__ << ": " << (void *)obj.d << endl; return 0;
}

  

 

  使用移动语义后

#include <iostream>
using namespace std; class Test
{
public:
Test(int a = 0)
{
d = new int(a);
cout << "cs" << this <<endl;
} Test(const Test & tmp)
{
d = new int;
*d = *(tmp.d);
cout << "copy\n";
} Test(Test && tmp)
{ // 移动构造函数
d = tmp.d;
tmp.d = NULL; // 将临时值的指针成员置空
cout << "mv" << this << endl;
} ~Test()
{
if(d != NULL)
{
delete d;
cout << "delete d\n";
}
cout << "ds: " << this << endl;
} int * d;
}; Test GetTmp()
{
Test h;
cout << "Resource from " << __func__ << ": " << (void *)h.d << endl;
return h;
} int main()
{
Test&& obj = GetTmp();
cout << "Resource from " << __func__ << ": " << (void *)obj.d << endl; return 0;
}

  

 

  

int main()
{
//Test&& obj = GetTmp();
Test obj = GetTmp();
cout << "Resource from " << __func__ << ": " << (void *)obj.d << endl; return 0;
}

  

c++ 11 移动语义的更多相关文章

  1. C++11移动语义之一(基本概念)

    摘要 移动语义是C++11的新特性之一,利用移动语义可以实现对象的移动而非拷贝.在某些情况下,可以大幅度的提升性能.本文将介绍C++11移动语义中的一些基本概念. 表达式 表达式是由一个或者多个运算对 ...

  2. c++ 11 移动语义、std::move 左值、右值、将亡值、纯右值、右值引用

    为什么要用移动语义 先看看下面的代码 // rvalue_reference.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #includ ...

  3. c++11 移动语义move semantics

    performance, expensive object copies move semantics, temporary objects implemented with rvalue refer ...

  4. 冒号课堂 编程范式与OOP思想

    上篇:编程范式与编程语言 第1课 开班导言 第2课 重要范式 第3课 常用范式 第4课 重温范式 第5课 语言小谈 第6课 语言简评 下篇:抽象机制与对象范式 第7课 抽象封装 第8课 抽象接口 第9 ...

  5. 《实战突击:PHP项目开发案例整合(第2版)(含DVD光盘1张)》

    <实战突击:PHP项目开发案例整合(第2版)(含DVD光盘1张)> 基本信息 作者: 徐康明    辛洪郁 出版社:电子工业出版社 ISBN:9787121221378 上架时间:2014 ...

  6. 【C++ STL应用与实现】18: 怎样使用迭代器适配器

    本系列文章的文件夹在这里:文件夹. 通过文件夹里能够对STL整体有个大概了解 前言 本文介绍了STL中的迭代器适配器(iterator adapter)的概念及其用法演示样例.迭代器适配器能够和标准库 ...

  7. 地区sql

    /*Navicat MySQL Data Transfer Source Server : localhostSource Server Version : 50136Source Host : lo ...

  8. c++11的右值引用、移动语义

    对于c++11来说移动语义是一个重要的概念,一直以来我对这个概念都似懂非懂.最近翻翻资料感觉突然开窍,因此记下.其实搞懂之后就会发现这个概念很简单,并无什么高深的地方. 先说说右值引用.右值一般指的是 ...

  9. 【转】C++11 标准新特性: 右值引用与转移语义

    VS2013出来了,对于C++来说,最大的改变莫过于对于C++11新特性的支持,在网上搜了一下C++11的介绍,发现这篇文章非常不错,分享给大家同时自己作为存档. 原文地址:http://www.ib ...

随机推荐

  1. 超详MySQL5.7.17压缩包安装图文教程

    靠吹风机暖手写完这篇教程...网络上关于MySQL 5.7.17的安装教程很少且不详细,所以总结了这样一篇文章,希望能帮到大家:(相较于Oracle的安装,MySQL还是简单得多) 1. 下载网址:h ...

  2. oracle substr函数

    //截取下划线后的字符串 select substr('GY_272',instr('GY_272', '_', -1, 1)+1)   from dual select substr('GY_272 ...

  3. Static需谨慎

    Static Cling Sticking Your Code To Things Unnecessarily Static Cling is a code smell used to describ ...

  4. Qt下拉对话框 ComboBox的用法

    介绍 ComboBox是Qt的下拉菜单的一个控件,通过下拉菜单选择不同的选项,样式如图: 基本用法 m_ComBox = ui.comboBox; //设置默认显示值的索引,从0开始 m_ComBox ...

  5. Harbor私有仓库中如何彻底删除镜像释放存储空间?

    简介: Harbor私有仓库运行一段时间后,仓库中存有大量镜像,会占用太多的存储空间.直接通过Harbor界面删除相关镜像,并不会自动删除存储中的文件和镜像.需要停止Harbor服务,执行垃圾回收命令 ...

  6. HTTP请求处理流程 MVC核心(MVC就是扩展了一个HttpModule)

    访问Localhost:8080/Home/index.aspx 在调用MVC扩展的UrlRoutingModule的时候  会先检查物理路径文件是否存在  存在的话就不执行MVC中的路由匹配规则  ...

  7. SpringMVC使用Swagger

    Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件的方法,参数和模型紧密集成到服 ...

  8. hdu-1430 魔板 康拓展开+映射优化

    给定三种操作,将排列A转化为排列B,求最少步骤. 这种题目可以只跑一次bfs,比如只跑"12345678",那么如果遇到"23456781"->某个字符串 ...

  9. Linux下执行.sh命令出现-bash: ./bin/start.sh: /bin/bash^M: bad interpreter: No such file or directory

    原因是 文件的格式是dos,修改为unix 就OK了 查看文件格式  用vim 打开出错的文件    按 ESC键     再按shift+冒号   输入 set  ff  回车   可以看见 该文件 ...

  10. prometheus告警配置注意事项

    global: scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minut ...