Участник класса ссылки константы продлевает жизнь временного файла?

Почему делает это:

#include <string>
#include <iostream>
using namespace std;

class Sandbox
{
public:
    Sandbox(const string& n) : member(n) {}
    const string& member;
};

int main()
{
    Sandbox sandbox(string("four"));
    cout << "The answer is: " << sandbox.member << endl;
    return 0;
}

Дайте вывод:

Ответ:

Вместо:

Ответ: четыре

157
задан NathanOliver- Reinstate Monica 17 August 2018 в 23:40
поделиться

3 ответа

. Только ссылки local const продлевают срок службы.

Стандарт определяет такое поведение в §8.5.3/5, [dcl.init.ref], раздел об инициализаторах объявлений ссылок. Ссылка в вашем примере привязана к аргументу конструктора n и становится недействительной, когда привязанный объект n выходит за пределы области видимости.

Увеличение срока службы не является транзитивным через аргумент функции. §12.2 / 5 [class.porary]:

Второй контекст - это когда ссылка привязана к временному объекту. Временный объект, к которому привязана ссылка, или временный объект, являющийся полным объектом для подобъекта, к которому привязан временный объект, сохраняется в течение всего времени существования ссылки, за исключением случаев, указанных ниже. Временная привязка к ссылочному элементу в ctor-initializer конструктора (§12.6.2 [class.base.init]) сохраняется до выхода из конструктора. Временная привязка к параметру ссылки в вызове функции (§5.2.2 [expr.call]) сохраняется до завершения полного выражения, содержащего вызов.

154
ответ дан 23 November 2019 в 21:47
поделиться

Вот самый простой способ объяснить, что произошло:

In main () вы создали строку и передали ее конструктору. Этот экземпляр строки существовал только в конструкторе. Внутри конструктора вы назначили член, указывающий непосредственно на этот экземпляр. Когда область видимости покинула конструктор, экземпляр строки был уничтожен, а член затем указал на строковый объект, который больше не существовал. Если Sandbox.member указывает на ссылку за пределами его области видимости, эти внешние экземпляры не будут находиться в области видимости.

Если вы хотите исправить свою программу, чтобы она отображала желаемое поведение, внесите следующие изменения:

int main()
{
    string temp = string("four");    
    Sandbox sandbox(temp);
    cout << sandbox.member << endl;
    return 0;
}

Теперь temp выйдет за пределы области видимости в конце main (), а не в конце конструктора. Однако это плохая практика. Ваша переменная-член никогда не должна быть ссылкой на переменную, существующую вне экземпляра. На практике вы никогда не знаете, когда эта переменная выйдет за пределы области видимости.

Я рекомендую определить Sandbox.member как константный строковый член ; Это скопирует данные временного параметра в переменную-член, вместо того, чтобы назначать переменную-член как сам временный параметр.

24
ответ дан 23 November 2019 в 21:47
поделиться

Потому что ваша временная строка вышла из области видимости после возвращения конструктора Sandbox, и стек, занятый ею, был возвращен для других целей.

Вообще, вы никогда не должны сохранять ссылки надолго. Ссылки хороши для аргументов или локальных переменных, но никак не для членов класса.

0
ответ дан 23 November 2019 в 21:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: