开发者

C++ const lvalue references

Assuming I have:

  • class A which is non-copyable
  • class B which has as a member, const A& a (and takes an A in its constructer and sets it in its initialization list)
  • a function A GenerateA();

Does this mean that it should be valid to do: B(GenerateA()) ?

i.e, does 开发者_如何学运维the const ref mean that no copy of the A that generateA() returns is done? And does that mean that the scope of the returned temporary is extended for as long as B exists?

EDIT: Addon question from the comments: Is it acceptable to return a A& from GenerateA() to a local A, if the lvalue is a const A&?

Thanks!


If A is non-copyable, then the function A GenerateA() is invalid since returning by value requires creating a copy.

If the function returns a reference instead (i.e. A &GenerateA()) and the reference is to a locally created A object, it becomes invalid as soon as the function exits. C++ doesn't have any form of garbage collection, so there is no way to "extend" the lifetime of an object as long as it is in use.


As it has already been stated by others, A GenerateA() cannot compile if A is not copyable.

Regarding the const ref : no, the lifetime of the temporary will not be extended to the lifetime of B. The standard [12.2.5] states :

A temporary bound to a reference member in a constructor's ctor-initializer (12.6.2) persists until the constructor exits. [...] A temporary bound to the returned value in a function return statement (6.6.3) persists until the function exits.

So yes, extension of the lifetime of a temporary exists in some contexts (and is sometime truly useful : see this article), but not in the one you presented.

Regarding your last question, it's not legal to return a reference to a local variable from GenerateA() (and binding the result to a const reference won't be of any help).


Yes and No.

Yes, the const reference will bind to the temporary variable. No, const references which are class members do not extend lifetime the way const references with automatic duration do.


Here's an example:

#include <iostream>
using namespace std;

int& GenX(bool reset)
{
    static int* x = new int;
    *x = 100;
    if (reset)
    {
        delete x;
        x = new int;
        *x = 200;
    }
    return *x;
}

class YStore
{
public:
    YStore(int& x);
    int& getX() { return my_x; }
private:
    int& my_x;
};

YStore::YStore(int& x)
 : my_x(x)
{
}

int main()
{
    YStore Y(GenX(false));
    cout << "X: " << Y.getX() << endl;
    GenX(true); // side-effect in Y
    cout << "X: " << Y.getX() << endl;
    return 0;
}

Output:

X: 100
X: 200
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜