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. MySQL中group by , sum , case when then 的使用

    在我们使用数据库的时候,可能会遇到需要进行统计的情况. 比如需要统计一下,下表中各个年份的胜负场数. 遇到这样的情况,我们应该怎么办呢? 在mysql中我们可以使用group by sum  case ...

  2. Vertical viewport was given unbounded height

    new Expanded( child: new ListView( ..... ) ); +++++++++++++++ 可以通过指定shrinkWrap = true为了你ListView. Li ...

  3. PHP防止网页快速刷新+代理ip访问

    前几天网站收到了一些CC攻击,比较郁闷...这里分享一下,防止网页自动刷新的方法以及阻止代理IP访问网站的方法,代码是分开的,两个功能,需要那个用那个,可以自定义时间间隔,这个代码不止可以防CC攻击, ...

  4. python爬虫——跟踪登录过程以及意外的发现(4)

    新浪微博的消息还是很多的,值得弄个账号去爬.不过都有账号了,还需要特意再搞一个吗? 直接上去跟踪.分别使用www和wap端登录: wap端相对简单,form表单都没有用到前面传的数据.但是我看到表单时 ...

  5. spool例子

    set head offset echo offset feed offset heads offset pages 50000SET NEWPAGE NONEcolumn yesterday new ...

  6. Js异常的处理

    博客1:  https://segmentfault.com/a/1190000011481099 express中的异常处理:https://blog.fundebug.com/2017/12/06 ...

  7. C#---装箱、拆箱的一个案例

    using System; namespace ConsoleApplication1 { interface IInterface { void Add(int num); } struct Tes ...

  8. 日常英语---八、REBOOT - What is the difference? -MapleStory

    日常英语---八.REBOOT - What is the difference? -MapleStory 一.总结 一句话总结: trade transfer drop_rate equipment ...

  9. JAVA文件操作类和文件夹的操作代码示例

    JAVA文件操作类和文件夹的操作代码实例,包括读取文本文件内容, 新建目录,多级目录创建,新建文件,有编码方式的文件创建, 删除文件,删除文件夹,删除指定文件夹下所有文件, 复制单个文件,复制整个文件 ...

  10. gunicorn flask nginx环境配置

    防火墙端口设置****修改后要重启生效(有时在控制面板中设置80端口无法生效) /etc/init.d/iptables statusservice iptables stopfirewall-cmd ...