C++左值与右值、禁用函数
左值&与右值&&
右值引用(Rvalue Referene)是C++新标准(C++11)中引入的新特性,它实现了转移语义(Move Sementics)和精确传递(Perfect Forwarding)。它的主要目的有两个方面:
- 消除两个对象交互时不必要的对象拷贝,节省运算存储资源,提高效率。
- 能够更简洁明确地定义泛型函数。
要点:
- C++( 包括 C) 中所有的表达式和变量要么是左值,要么是右值。
- 在多条代码中都可以使用,都是左值。(非临时对象)
- 右值只在当前语句有效,赋值没有意义。(临时对象)
- 立即数都是右值。
- 对于需要动态申请大量资源的类,应该设计转移构造函数和转移赋值函数,以提高应用程序的效率。
- 编译器只对右值引用才能调用转移构造函数和转移赋值操作符
在现有的 C++ 机制中,我们可以定义拷贝构造函数和赋值操作符。要实现转移语义,需要定义转移构造函数,还可以定义转移赋值操作符。对于右值的拷贝和赋值会调用转移构造函数和转移赋值操作符。如果转移构造函数和转移拷贝操作符没有定义,那么就遵循现有的机制,拷贝构造函数和赋值操作符会被默认调用。
标准库提供了函数std::move
,这个函数可以用来将左值引用转换为右值引用。
参考:右值引用与转移语义
禁用函数 = delete
C++ 的类有四类特殊成员函数,它们分别是:默认构造函数、析构函数、拷贝构造函数、赋值运算符。这些类的特殊成员函数负责创建、初始化、销毁,或者拷贝类的对象。如果程序员没有显式地为一个类定义某个特殊成员函数,而又需要用到该特殊成员函数时,则编译器会隐式的为这个类生成一个默认的特殊成员函数。
某些情况下,假设我们不允许发生类对象之间的拷贝和赋值,可是又无法阻止编译器隐式自动生成默认的拷贝构造函数以及赋值操作符,就可以使用这种操作。
// coding standard: disallow when not used
T(void) = delete; // default ctor (1)
~T(void) = delete; // default dtor (2)
T(const T&) = delete; // copy ctor (3)
T(const T&&) = delete; // move ctor (4)
T& operator= (const T&) = delete; // copy assignment (5)
T& operator= (const T&&) = delete; // move assignment (6)
禁止隐式转换:
// disallow implicit promotion's
template <class T> operator T(void) = delete;
template <class T> Vuint64& operator= (const T) = delete;
template <class T> Vuint64& operator|= (const T) = delete;
template <class T> Vuint64& operator&= (const T) = delete;
参考:https://stackoverflow.com/questions/5513881/meaning-of-delete-after-function-declaration
默认函数 = default
类的其它几类特殊成员函数和默认构造函数一样,当存在用户自定义的特殊成员函数时,编译器将不会隐式的自动生成默认特殊成员函数,而需要程序员手动编写,加大了程序员的工作量。即使是空函数,手动编写的特殊成员函数的代码执行效率也比编译器自动生成的特殊成员函数低。
为了解决这两个问题,C++11 标准引入了一个新特性:defaulted 函数。程序员只需在函数声明后加上“=default;”,就可将该函数声明为 defaulted 函数,编译器将为显式声明的 defaulted 函数自动生成函数体。
参考:C++11 标准新特性:Defaulted 和 Deleted 函数
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 using1174@foxmail.com
文章标题: C++左值与右值、禁用函数
文章字数: 925
本文作者: Jun
发布时间: 2018-12-06, 21:19:00
最后更新: 2019-01-24, 15:39:27
原始链接: http://yoursite.com/2018/12/06/C-左值与右值、禁用函数/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。