c++11 以后支持了nrvo(命名的rvo),先来一张图

直接贴代码

#include <iostream>
#include <string>
#include <vector>
using namespace std;

class BigObject {
public:
    BigObject() { cout << "Constructor\n"; }
    ~BigObject() { cout << "Destructor\n"; }
    BigObject(BigObject const&) { cout << "Copy Constructor\n"; }
    BigObject& operator=(BigObject const&) {
        cout << "Assignment Operator\n";
        return *this;
    }
    BigObject(BigObject&&) { cout << "Move Constructor\n";}
};
// rvo
BigObject f1() { return BigObject(); }
// nrvo => named rvo
BigObject f2() { 
    BigObject obj;
    return obj;
}
BigObject f3() {
    BigObject obj[1];
    return obj[0];
}
BigObject f4() { return std::move(BigObject()); s}
BigObject f5() {
    BigObject obj;
    return const_cast<BigObject&>(obj);
}

int main(int argc, char* argv[]) {
    cout << "1 ------------------------" << endl;
    { BigObject obj1 = f1();}
    cout << "2 ------------------------" << endl;
    { BigObject obj2 = f2();}
    cout << "3 ------------------------" << endl;
    {BigObject obj3 = f3();}
    cout << "4 ------------------------" << endl;
    {BigObject obj4 = f4();}
    cout << "5 ------------------------" << endl;
    {BigObject obj5 = f5();}

    return 0;
}
1 ------------------------
Constructor
Destructor
2 ------------------------
Constructor
Destructor
3 ------------------------
Constructor
Copy Constructor
Destructor
Destructor
4 ------------------------
Constructor
Move Constructor
Destructor
Destructor
5 ------------------------
Constructor
Copy Constructor
Destructor
Destructor
  1. f1 中返回了简单对象, rvo
  2. f2 中返回了命名的对象, nrvo
  3. f3 多个对象返回了其中一个,没有rvo
  4. f4 使用move,反而没有rvo
  5. f5 cast 之后也不存在 rvo