本文共 1390 字,大约阅读时间需要 4 分钟。
首先,什么是左值、右值?
左值是能出现在等号左边和右边的变量,右值是只能出现在等号右边的变量(或表达式)。
左值引用为 & , 而右值引用为 &&。
那么为什么需要右值引用呢?主要是为了处理c++临时对象的低效的问题,使用右值引用可以减少不必要的拷贝构造。
举个例子:
#includeusing namespace std;class A {public: A(int a) { cout << "constructor" << endl; this->num = new int(a); } A(const A& t) { cout << "copy" << endl; this->num = new int(*(t.num)); } int* num;};A get_A() { A a(10); return a;}int main() { A test = get_A();}
输出结果为:
constructor
copy copy调用了两次拷贝构造函数(一次用在临时变量的拷贝,一次用在test的拷贝)。使用g++可能会得到不同的输出,因为g++对此进行了优化,需要使用参数-fno-elide-constructors。
那么我们通过实现多一个函数A(A&& t)来使用右值引用:
class A {public: A(int a) { cout << "constructor" << endl; this->num = new int(a); } A(const A& t) { cout << "copy" << endl; this->num = new int(*(t.num)); } A(A&& t) { cout << "move" << endl;; this->num = t.num; } int* num;};A get_A() { A a(10); return a;}int main() { A test = get_A();}
输出结果为:
constructor
move move可以看到,使用右值引用,避免了不必要的拷贝构造,而只是将资源(此处为num变量)的归属做了调整。
另外,我们还可以使用std::move()函数将左值变为右值来避免拷贝构造。
class A {public: A(int a) { cout << "constructor" << endl; this->num = new int(a); } A(const A& t) { cout << "copy" << endl; this->num = new int(*(t.num)); } A(A&& t) { cout << "move" << endl;; this->num = t.num; } int* num;};A get_A() { A a(10); return a;}int main() { A test(10); A b(test); A c(std::move(test));}
输出结果为:
constructor
copy move转载地址:http://twwob.baihongyu.com/