翻译「C++ Rvalue References Explained」C++右值引用详解 Part5:右值引用就是右值吗?
本文为第五部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/cpp-rvalue-references-explained-introduction.html。
右值引用就是右值吗?
同之前一样,给出一个X类,让我们可以重载它的拷贝构造函数和拷贝赋值操作符来实现move语义。现在做如下考虑:
void foo(X&& x)
{
X anotherX = x;
// ...
}
一个有趣的问题就是,在foo函数内,哪一个x的拷贝构造函数重载将会被调用。这里,x是一个被声明为右值引用的变量,也就是说,一个在一般情况下或者在更好的情况下(即使并不是必须的)指代一个右值。因此,也许可以期待x本身应该像是一个右值绑定,也就是说:
X(X&& rhs);
应该被调用。换另一种说法,一个人可能会期待任何被声明为右值引用的,其本身也是一个右值。然后右值引用的设计者们采取了更为微妙的一种解决方案:
被声明为右值引用的可能既是左值也可能是右值。这里判断的标准在于:如果它有名字,那么它就是左值。否则就是右值。
就上面的例子,被声明为右值引用的有了一个名字,那么因此它是一个左值:
void foo(X&& x)
{
X anotherX = x; // 调用 X(X const & rhs)
}
这里就是一个被声明为右值引用并且并没有名字,因此它是一个右值:
X&& goo();
X x = goo(); // 调用 X(X&& rhs) 因为在表达式的右手边
// 并没有名字
这里有关于这种设计的原理阐述:假设默许move语义发生在一个有名字的东西上面,如下:
X anotherX = x;
// x依然在作用域内!
将是十分危险且混乱的,并且是很容易出错的。因为我们刚刚移动的东西,依然在随后的代码中可以被访问到。但是move语义的整个要点在于它就是应用在那些并不用在意移动后的情况的对象上,严格意义上而言,那些我们从它那里移动后会销毁并且放任不管是没有问题的。因此才有了这个规则:“如果它有个名字,那么它是一个左值。”
这里有一个例子显示了「如果它有一个名字规则」的重要性。假设你已经写了一个叫做Base的类,然后你通过重载Base的拷贝构造函数和赋值操作符来实现move语义。
Base(Base const & rhs); // 非move语义
Base(Base&& rhs); // move语义
现在你写了一个Derived的类,他继承于Base。为了保证move语义被实施在Derived对象的Base部分,你必须也同时重载Derived的拷贝构造函数和赋值操作符。让我们来看一下拷贝构造函数,拷贝赋值操作符的处理是类似的。对应于左值的版本比较简单直接:
Derived(Derived const & rhs)
: Base(rhs)
{
// 针对Derived特定的操作
}
对应于右值的版本有一个很大的微妙的不同。下面就是有人没有意识到「如果它有一个名字规则」可能写出来的:
Derived(Derived&& rhs)
: Base(rhs) // 错误:rhs是一个左值
{
// 针对Derived特定的操作 f
}
如果我们像那样写代码,那么non-moving的Base拷贝构造函数的版本将会被调用,因为rhs有一个名字,是一个左值。我们想要调用的是Base的moving构造函数,我们需要这样写:
Derived(Derived&& rhs)
: Base(std::move(rhs)) // 好,调用Base(Base&& rhs)
{
// 针对Derived特定的操作
}
翻译「C++ Rvalue References Explained」C++右值引用详解 Part5:右值引用就是右值吗?的更多相关文章
- 翻译「C++ Rvalue References Explained」C++右值引用详解 Part1:概述
本文系对「C++ Rvalue References Explained」 该文的翻译,原文作者:Thomas Becker. 该文较详细的解释了C++11右值引用的作用和出现的意义,也同时被Scot ...
- 翻译「C++ Rvalue References Explained」C++右值引用详解 Part3:右值引用
本文为第三部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/4220233.html. 右值引用 如果x是任意类型,那么x&&则被称作一个 ...
- 翻译「C++ Rvalue References Explained」C++右值引用详解 Part8:Perfect Forwarding(完美转发):解决方案
本文为第八部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/cpp-rvalue-references-explained-introduction.ht ...
- 翻译「C++ Rvalue References Explained」C++右值引用详解 Part6:Move语义和编译器优化
本文为第六部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/cpp-rvalue-references-explained-introduction.ht ...
- 翻译「C++ Rvalue References Explained」C++右值引用详解 Part4:强制Move语义
本文为第四部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/4220233.html. 强制Move语义 众所周知,正如C++标准的第一修正案所陈述:“委 ...
- 「翻译」Unity中的AssetBundle详解(二)
为AssetBundles准备资源 使用AssetBundles时,您可以随意将任何Asset分配给所需的任何Bundle.但是,在设置Bundles时,需要考虑一些策略.这些分组策略可以使用到任何你 ...
- 「翻译」Unity中的AssetBundle详解(一)
AssetBundles AssetBundle是一个存档文件,其中包含平台在运行时加载的特定资产(模型,纹理,预制,音频剪辑,甚至整个场景).AssetBundles可以表示彼此之间的依赖关系;例如 ...
- Linux 小知识翻译 - 「协议(protocol)」
对于理解服务器和网络来说,「协议」是不可缺少的概念. 「协议(protocol)」有「规则,规定」的意思. 实际上「协议」的函数很广,在通信领域,「协议」规定了「在通信时,什么样的情况下,以什么样的顺 ...
- 「MoreThanJava」Day 7:接口详解
「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 ...
随机推荐
- Javascript 图片左右滑动与切换
Html代码 : <div class="v_out v_out_p"> <div class="prev"> <a href=& ...
- SSL证书在线工具
证书在线工具 如果您是第一次申请SSL证书,如果您对您的服务器如何使用SSL证书还不熟悉的话,我们推荐您使用本套工具,本套工具支持所有SSL服务器证书格式和各种WEB服务器.帮助您在线生成CSR文件, ...
- android学习笔记27——Activity
Activity配置==> android应用程序要求所有的应用程序组件都需要进行显示配置后,才可正常使用.包括:Activity.Service.BroadCastReceiver.Conte ...
- insmod module_param 模块参数
模块参数 引导模块时,可以向它传递参数.要使用模块参数加载模块,这样写: insmod module.ko [param1=value param2=value ...] 为了使用这些参数的值,要在模 ...
- [内核同步]自旋锁spin_lock、spin_lock_irq 和 spin_lock_irqsave 分析
转自:http://blog.csdn.net/wh_19910525/article/details/11536279 自旋锁的初衷:在短期间内进行轻量级的锁定.一个被争用的自旋锁使得请求它的线程在 ...
- 【转】SQLServer XML类型
SQL Server从2005起开始支持xml类型,这个数据类型对于后期的改变非常有用.一对多的关系在后期变成了多对多的关系,XML类型就是一个不错的选择. 1.创建测试数据 创建表 --创建表,包含 ...
- Team Foundation Server
概述 (通常记作“TFS”) 是一种为 Microsoft 产品提供 源代码管理. 数据收集. 报告和项目跟踪,而为协作 软件开发 的项目. 可作为独立的软件,或 Visual Studio Team ...
- 在mac上安装svn客户端
mac 10.8上面,默认是没有svn客户端的,可以通过以下两种方式来安装: 1.单独安装xcode命令行工具,安装完成后,在终端中就可以使用svn命令了,目前版本是1.6.18: 2.去 ...
- 黄聪:wordpress工作原理
WP初始化的过程:当你输入<yourlink>/wordpress对wordpress进行初始化时,wordpress默认会找根目录下的index.php页面,看一下index.php页面 ...
- pycharm 格式化代码
有时候将空格键和tab键混用,在windows上没什么事情,但是如果移动到linux就会有问题,所以我们在移动到linux上之前要先格式化一下代码: ctrl+alt+L可以格式化,但是和锁屏快捷键冲 ...