RVO--Return Value Optimization
概述
返回值优化(Return Value Optimization,简称RVO)是一种编译器优化机制:
当函数需要返回一个对象的时候,如果自己创建一个临时对象用户返回,那么这个临时对象会消耗一个构造函数(Constructor)的调用、一个复制构造函数的调用(Copy Constructor)以及一个析构函数(Destructor)的调用的代价。而如果稍微做一点优化,就可以将成本降低到一个构造函数的代价,这样就省去了一次拷贝构造函数的调用和依次析构函数的调用。
下面我们看个例子
#include <iostream> using namespace std; class Rational { public: Rational(int numerator = 0, int denominator = 1) : n(numerator), d(denominator) { cout << "Constructor Called..." << endl; } ~Rational() { cout << "Destructor Called... n:" << n << "d:" << d << endl; } Rational(const Rational& rhs) { this->d = rhs.d; this->n = rhs.n; cout << "Copy Constructor Called..." << endl; } int numerator() const { return n; } int denominator() const { return d; } private: int n, d; }; const Rational operator*(const Rational& lhs, const Rational& rhs) { cout << "----------- Enter operator* -----------" << endl; Rational tmp(lhs.numerator() * rhs.numerator(), lhs.denominator() * rhs.denominator()); cout << "----------- Leave operator* -----------" << endl; return tmp; } int main(int argc, char **argv) { Rational x(1, 5), y(2, 9); Rational z = x * y; cout << "calc result: " << z.numerator() << "/" << z.denominator() << endl; return 0; }
使用gcc4.8.4运行:
Constructor Called... Constructor Called... ----------- Enter operator* ----------- Constructor Called... ----------- Leave operator* ----------- calc result: 2/45 Destructor Called... n:2d:45 Destructor Called... n:2d:9 Destructor Called... n:1d:5
tmp对象并没有生成和析构,这是为啥呢,原来gcc4.8.4默认开启了RVO优化,下面我们关闭看一下,使用-fno-elide-constructors
> g++ -fno-elide-constructors main.c > ./a.out Constructor Called... Constructor Called... ----------- Enter operator* ----------- Constructor Called... ----------- Leave operator* ----------- Copy Constructor Called... Destructor Called... n:2d:45 Copy Constructor Called... Destructor Called... n:2d:45 calc result: 2/45 Destructor Called... n:2d:45 Destructor Called... n:2d:9 Destructor Called... n:1d:5
这个才是我们理解的形式。