C ++ const lvalue ссылки - PullRequest
       313

C ++ const lvalue ссылки

9 голосов
/ 10 ноября 2010

Предполагая, что у меня есть:

  • класс A, который не подлежит копированию
  • класс B, который имеет в качестве члена const A & a (и принимает A в своем конструкторе и устанавливаетв списке инициализации)
  • функция A GenerateA();

Означает ли это, что это должно быть допустимо для: B (GenerateA ())?

т. е. означает ли const ref, что не сделана копия A, которую возвращает generateA ()?И означает ли это, что область действия возвращаемого временного объекта увеличивается до тех пор, пока существует B?

РЕДАКТИРОВАТЬ: вопрос о дополнении из комментариев: допустимо ли возвращать A & из GenerateA () в локальный A,если lvalue является константой A &?

Спасибо!

Ответы [ 4 ]

4 голосов
/ 10 ноября 2010

Если A не подлежит копированию, то функция A GenerateA() недопустима, поскольку для возврата по значению требуется создать копию.

Если функция возвращает ссылку (т.е. A &GenerateA()) иссылка на локально созданный объект A, он становится недействительным, как только выходит из функции.C ++ не имеет какой-либо формы сборки мусора, поэтому нет способа «продлить» время жизни объекта, пока он используется.

3 голосов
/ 10 ноября 2010

Как уже было сказано другими, A GenerateA() не может скомпилироваться, если A не копируется.

Относительно const ref: нет, время жизни временного не будет продлено до времени жизниB. Стандарт [12.2.5] гласит:

Временная привязка к элементу ссылки в ctor-initializer конструктора (12.6.2) сохраняется до выхода из конструктора.[...] Временная привязка к возвращенному значению в операторе возврата функции (6.6.3) сохраняется до выхода из функции.

Так что да, в некоторых случаях продление времени жизни временногоконтексты (и иногда действительно полезные: см. эту статью ), но не в том, который вы представили.

Что касается вашего последнего вопроса, возвращать ссылку на локальную переменную изGenerateA() (и привязка результата к константной ссылке не поможет).

0 голосов
/ 10 ноября 2010

Вот пример :

#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;
}

Выход:

X: 100
X: 200
0 голосов
/ 10 ноября 2010

Да и нет.

Да, ссылка const будет привязана к временной переменной. Нет, ссылки на const, являющиеся членами класса, не продлевают время жизни, как это делают ссылки на const с автоматической продолжительностью.

...