我何时应该T const&
返回?如果我不打算修改对象,我看不出它与按值返回有什么不同。并且通过const引用返回真的只意味着没有复制。所以当T const&
返回时有用。
答案 0 :(得分:5)
有两个原因可以让您更喜欢按const&
而不是按值返回。
首先是语义。通过const&
返回内容的代码告诉调用者显式,“这是您要求的只读版本。如果您想永久存储它,或者对其进行更改它,你有责任复制它。“这种返回类型的语义非常清楚,并且易于实施。
第二是优化。通过按值返回某些内容,可以从编译器中删除一些优化机会。 表示返回按值 的效率低于const&
返回的效率(事实上,相反的可能 >是真的 - 考虑一个在64位系统上返回char
的函数。它只是意味着您从编译器的优化工具箱中删除其中一个工具。还有另一种工具可以替换它 - 即,将调用与复制省略一起内联 - 所以这可能是一种清洗。这完全取决于背景。
我提到“语义学”是第一个原因,因为我认为它是最重要的。有很多变量需要优化和许多移动部件,因此通常很难知道编译器能够使用什么优化以及何时使用。然而有一件事是certian - 人类比混乱的语义更容易理解清晰的语义。
答案 1 :(得分:2)
您返回const T&
的常见情况是const
getter成员函数:
T& get() { return m_some_private_member; }
const T& get() const { return m_some_private_member; }
在这种情况下,您通常不想复制 - 您只想返回对某个对象的引用,并且为了const-correctness,您可能还需要提供const
getter。
答案 2 :(得分:1)
当你有足够稳定的物体时。
一个简单的例子是一个以这种方式返回内容的集合。有点主要职位描述。
对于nonconst&另一个常见的情况是返回你在参数中得到的东西(包括隐藏的this指针)。这可能适用于const&以类似的方式,但要注意风险,当你的param被绑定到一个临时的,将在短时间内消失。如果你有更好的工作会更好并返回const&更改内容后。
您可以返回对数据成员的引用,但它符合“不要泄漏您的内心”指南。
在任何情况下,如果您返回ref,您必须向客户提供有关有效性的文档。如果你开始编写这个描述,你会发现它是否有意义。
另一个明显的例子是身份对象,它可以(或假设)不被复制。有必要使用访问器,一个返回const&主流使用和另一个具有写访问权限。
答案 3 :(得分:0)
由于您指定的原因:没有复制。
如果要返回一个大对象,则返回一个const引用比该对象的副本更有效。
答案 4 :(得分:0)
不制作副本效率更高,特别是对于复杂类型或在其复制构造函数中执行大量工作的类型。
答案 5 :(得分: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
并有效防止此类滥用。