我读过很多关于回报价值优化的文章。然而,我不确定是否完全理解这是否是在以下情况下发生的事情(地址实际上总是相同的):
#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发生在这里?
答案 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
而不创建副本。