const <type>&amp; foo()与<type> foo()</type> </type>

时间:2010-01-11 21:27:57

标签: c++ optimization visual-c++ g++

非模板 类中,是否有理由更喜欢const <type>& foo();<type> foo();形式的函数返回签名? <type>是一种内在类型。如果<type>是类/结构对象呢?

同样感兴趣的是 const 这个函数是否有所不同:const <type>& foo() const;<type> foo() const;

E.g。在非模板类中,非模板函数:

const int& foo() const { return member_variable_; }

Versus

int foo() const { return member_variable_; }

5 个答案:

答案 0 :(得分:3)

对于基本类型,只需按值返回。没有理由通过const引用返回原语。

对于非原始类型,它取决于。

如果返回的值是函数的局部变量,则必须按值返回。否则,在调用者使用返回的引用之前,该变量将被销毁。

如果返回的值是类数据成员,那么您可以选择。

通过const引用返回可以避免副本,这可能是性能优势。但是,它将您的接口与实现联系起来,即数据成员和返回值必须是相同的类型。它也不太安全,因为调用者可以保留引用的时间长于对象的生命周期,例如:

const X& x = y->foo();
delete y;
// use x, oops!

按值返回会产生一个或两个副本,具体取决于您是否可以利用返回值优化(这可能适用于简单的get()方法)。此外,可以更有效地复制使用默认复制构造函数的对象副本(想一想:编译器可以简单地记忆数据)。

建议:以值返回开始,并在确定该调用/副本已知是性能问题后切换到const引用返回。

最后,另一种方法是通过参数返回,这对于更复杂的对象(例如字符串)非常有用:

void foo(X& return_val) { return_val = member_variable_; }

或:

void foo(X* return_val) {
    assert(return_val != 0);
    *return_val = member_variable_;
}

答案 1 :(得分:0)

如果需要返回一个值,则必须返回一个值 - const引用不是可接受的替代。但我怀疑你问的是这样的事情:

struct A {
   X x;
    ...
   X f1() { return x; }
   const X & f2() { return x; }
};

我从来没有为此提出过万无一失的准则。

答案 2 :(得分:0)

这完全取决于您想要做什么。

如果要返回对用户代码使用的对象的引用,则:

<type>& foo()  { ... }

如果要以只读方式返回对象的引用,只允许访问此对象类型的const函数,则:

const <type>& foo() { ... }

如果要返回对用户代码要使用的对象的引用,即使该类实例仅以只读方式使用(作为const),则:

<type>& foo() const { ... }

如果你想要以只读的方式返回对象的引用,只允许访问这个对象类型的const函数,并且如果类实例只在read(as const)中使用,那么事件:

const <type>& foo() const { ... }

只是要添加一个警告:不要返回对函数变量的引用,它们不能在函数外运行...

答案 3 :(得分:0)

const <type>& foo();

您的类中可能有类似容器元素的资源,而foo()会返回特定元素,如果您知道资源可用的时间足够长,您可能会返回对容器中元素的const引用,这样就可以避免不必要的分配/复制数据。 它可能是const,取决于您处理数据的方式,如果您不希望通过foo()返回的引用修改数据,那么将其设为const。也许你有一个案例,你想要修改资源和一些额外的工作需要完成,你会使非const。您可以在api用户中同时选择基于用例。

<type> foo();

返回资源<type>的新副本。这意味着要制作副本。这对于简单数据或可能共享值的情况很有用,并且您希望确保<type>的每个实例都是独立的 - 非共享,如某些字符串或int。

答案 4 :(得分:0)

如果类型是固有类型,则传递const refs不会提高性能,并且可能会降低性能,并且安全性较低;最好是按值传递和返回。我不是一个ASM人,但据我所知,通过引用返回意味着该值无法存储在寄存器中,因为它需要一个返回地址,因此可以禁用一些其他有用的优化;我对此并不积极。

如果是类或结构,则取决于值的生命周期;如果它是函数的局部函数则无法返回,否则,如果它是类成员,我更喜欢const类型&amp;返回因为它可以通过避免复制构造函数提供更好的性能。 (意见不同,因为by值被认为更安全)。它还使您不必实现复制构造函数或使用潜在的恶意默认值,这很好。