3

我应该什么时候回来T const&?如果我不打算修改对象,我看不出它与按值返回有何不同。通过 const 引用返回实际上只是意味着没有复制。所以什么时候返回T const&有用。

4

6 回答 6

6

const&您更愿意按价值而不是按价值返回的原因有两个。

首先是语义。返回某些内容的代码明确地const&告诉调用者,“这是您所要求的只读版本。如果您想永久存储它或对其进行更改,您有责任制作它的副本。 " 这种返回类型的语义非常清晰,并且易于执行。

二是优化。通过按值返回某些内容,您从编译器中删除了一些优化机会。这并不是说按值返回比按返回效率低const&(事实上,在相反的情况下可能是正确的——考虑一个char在 64 位系统上返回 a 的函数)。它只是意味着您从编译器的优化工具箱中删除了其中一个工具。还有另一个工具可以替换它——即,将调用与复制省略一起内联——所以这可能是一种清洗。这一切都取决于上下文。

我提到“语义”作为第一个原因是因为我认为它是最重要的。优化的变量太多,移动的部分太多,通常很难知道编译器将能够使用哪些优化以及何时使用。然而,一件事始终是确定的——清晰的语义比混乱的语义更容易被人类理解。

于 2013-06-06T14:18:00.227 回答
2

您要返回的常见情况const T&constgetter 成员函数:

T& get() { return m_some_private_member; }

const T& get() const { return m_some_private_member; }

在这种情况下,您通常不想复制 - 您只想返回对某个对象的引用,并且为了 const 正确性,您可能还需要提供一个constgetter。

于 2013-06-06T14:02:06.300 回答
1

当你有一个足够稳定的物体时。

一个简单的案例是一个以这种方式返回内容的集合。有点像主要的职位描述。

对于非常量和另一种常见的情况是返回你在参数中得到的内容(包括隐藏的 this 指针)。这可能以类似的方式适用于 const& ,但要注意风险,当您的参数绑定到一个将在短时间内消失的临时变量时。如果你得到 & 并在更改内容后返回 const& 会更好。

您可以返回对数据成员的引用,但它符合“不要泄露您的胆量”准则。

在任何情况下,如果您返回 ref,您必须向客户提供有关有效性的文件。如果您开始制定该描述,您将首先发现它是否有意义。

另一个明显的例子是身份对象,可以(或假定)不被复制。拥有访问器是有意义的,一个返回 const& 供主流使用,另一个具有写访问权限。

于 2013-06-06T14:22:29.117 回答
0

不制作副本效率更高,尤其是对于复杂类型或在其复制构造函数中执行大量工作的类型。

于 2013-06-06T14:04:49.617 回答
0

由于您指定的原因:没有复制

如果您要返回一个大对象,则返回一个 const 引用比返回该对象的副本更有效。

于 2013-06-06T14:02:46.270 回答
0

所以你可以避免你的功能像下面的那样被滥用?

class A
{
int x;

public:

int show()
{
return x;
}

A(int a)
{
        x = a;
}

A const& operator+(A& inp)
{

inp.x = this->x + inp.x;

return inp;
}

};

int main()
{
A a(1),b(2),c(0),d(420);
a + b = d;
std::cout<<b.show();

}

这给出,420作为输出。重载应该用作d = a + b,但没有什么可以阻止返回的引用被分配另一个对象。

如果将函数的返回类型设置为A const&返回的引用是常量,并且不能分配任何其他对象。因此,运算符只能用作d = a + b而不是允许a + b = d等。

g++ 给出错误error: passing ‘const A’ as ‘this’ argument of ‘A& A::operator=(const A&)’ discards qualifiers并有效地防止这种滥用。

于 2013-06-06T14:30:49.397 回答