通过引用返回时返回值优化

时间:2013-02-18 11:06:27

标签: c++ reference return-value return-value-optimization return-by-reference

我读过很多关于回报价值优化的文章。然而,我不确定是否完全理解这是否是在以下情况下发生的事情(地址实际上总是相同的):

#include "stdafx.h"

class Type
{
public:
    Type(int a) { m_a = a; }
private:
    Type(const Type & other) {}
    int m_a;
};

class Base
{
public:
    Base() : instance(42) {}
    virtual Type & GetType()
    {
        printf("Base: Address of instance: %i\n", &instance);
        return instance;
    }

private:
    Type instance;
};

class Derived : public Base
{
public:
    virtual Type & GetType()
    {
        printf("Derived\n");
        return Base::GetType();
    }
};

int main()
{
    printf("Base class\n");
    Base b;
    printf("Main: Address of instance: %i\n", &(b.GetType()));

    printf("\nDerived class\n");
    Derived d;
    printf("Main: Address of instance: %i\n", &(d.GetType()));
}

通过引用返回总是确保没有调用复制构造函数吗? 或RVO发生在这里?

2 个答案:

答案 0 :(得分:4)

  

通过引用返回总是确保没有调用复制构造函数吗?

RVO是一种优化技术。标准不保证。当按值返回时,大多数编译器都会应用RVO。

virtual Type & GetType()
        ^^^^^^

这里通过引用返回,这意味着不需要创建副本,因此没有复制构造函数调用的开销,因此没有RVO的机会或范围。

  

地址实际上始终相同

地址实际上总是相同的,因为它们是同一类成员的地址。

答案 1 :(得分:3)

  

通过引用返回总是确保没有调用复制构造函数吗?

是。当您通过引用传递或返回时(而不是通过值传递/返回),不会构造任何副本。

  

RVO发生在这里?

由于您通过引用返回,因此RVO与此无关。 RVO是一种优化技术,它包括消除在按值返回时创建的冗余副本

如果你有这样的功能,RVO可能会占据一席之地:

Type GetType()
{
    Type instance;
    //...
    return instance;
}
//...
Type t = GetType();

然后使用RVO,编译器会尝试消除多余的复制构造函数析构函数调用,这意味着来自instance的本地GetType函数将被分配到变量t而不创建副本。