C++移动语义及拷贝优化
我们知道在传统C++程序中,如果函数的返回值是一个对象的话,可能需要对函数中的局部对象进行拷贝。如果该对象很大的话,则程序的效率会降低。
在C++ 11以后,出现的移动语义(Move Semantic)及拷贝优化(Copy Elision)都是解决这个问题的方法。这篇博文简单探探这些技术。
再谈移动语义
对于C++ 11移动语义的介绍,我之前写过一篇博客《C++11中的移动语义》进行了介绍,这里我再进行简单的总结。
左值和右值
C++中如何区分一个变量是左值还是右值呢?
- 左值一般是可寻址的变量,右值一般是不可寻址的字面常量或者是在表达式求值过程中创建的可寻址的无名临时对象;
- 左值具有持久性,右值具有短暂性。
左值引用的符号为"&"(传统C++中的引用);右值引用的符号为"&&"(C++ 11中的新特性)
移动构造函数和移动赋值函数
移动语义和拷贝语义是相对于的,移动类似于计算机中对文件操作的剪切,而拷贝类似于文件的复制。
我们可以定义拷贝构造函数和赋值函数进行对象的复制,如果没有定义,编译器会帮我们生产默认的实现。要实现转移语义,需要定义转移构造函数,当然还可以定义转移赋值操作符。对于右值的拷贝和赋值会调用转移构造函数和转移赋值操作符。如果转移构造函数和转移拷贝操作符没有定义,那么拷贝构造函数和赋值操作符会被调用。
移动构造函数和移动赋值函数都是形参(Parameter)为右值引用的函数,下面看一个例子。
struct Foo {
Foo() {
cout << "Constructed" << endl; }
Foo(const Foo &) {
cout << "Copy-constructed" << endl; }
Foo(Foo &&) {
cout << "Move-constructed" << endl; }
~Foo