1

我已经阅读了很多关于返回值优化的文章。但是我不确定是否完全理解在以下情况下是否会发生这种情况(地址实际上总是相同的):

#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是否在这里进行?

4

2 回答 2

4

按引用返回是否始终确保不调用复制构造函数?

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

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

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

地址实际上总是相同的

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

于 2013-02-18T11:13:58.150 回答
3

按引用返回是否始终确保不调用复制构造函数?

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

RVO在这里举行吗?

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

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

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

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

于 2013-02-18T11:09:51.240 回答