Делает ссылку-член класса продлить жизнь временную?
почему это:
#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;
}
дать выход:
ответ:
вместо:
ответ: четыре!--2-->
5 ответов:
только local
const
ссылки продлевают срок службы.стандарт определяет такое поведение в §8.5.3 / 5, [dcl.в этом.ref], раздел об инициализаторах ссылочных объявлений. Ссылка в вашем примере привязана к аргументу конструктора
n
, и становится недействительным, когда объектn
обязательно выходит из области видимости.продление срока службы не является транзитивным через аргумент функции. §12.2/5 [класс.временно]:
второй контекст-это когда ссылка привязана к временной. Временное, к которому привязана ссылка, или временное, которое является полным объектом для подобъекта, к которому привязана временная ссылка, сохраняется в течение всего срока действия ссылки, за исключением случаев, указанных ниже. Временная привязка к ссылочному члену в ctor-инициализаторе конструктора (§12.6.2 [class.основа.init]) сохраняется до завершения работы конструктора. Временная привязка к ссылке параметр в вызове функции (§5.2.2 [expr.вызов]) сохраняется до завершения полного выражения, содержащего вызов.
вот самый простой способ объяснить, что произошло:
в main () вы создали строку и передали ее в конструктор. Этот экземпляр строки существовал только в конструкторе. Внутри конструктора вы назначили член для указания непосредственно на этот экземпляр. Когда область покинула конструктор, экземпляр string был уничтожен, а член затем указал на объект string, который больше не существовал. Имея Песочницу.член указывает на ссылку вне его области не будет содержать эти внешние экземпляры в области видимости.
Если вы хотите исправить свою программу для отображения желаемого поведения, внесите следующие изменения:
int main() { string temp = string("four"); Sandbox sandbox(temp); cout << sandbox.member << endl; return 0; }
теперь темп будет переходить из области видимости в конце функции main (), а не в конце конструктора. Однако, это плохая практика. Переменная-член никогда не должна быть ссылкой на переменную, которая существует вне экземпляра. На практике, вы никогда не знаете, когда эта переменная выйдет из области видимости.
Что Я рекомендуется определить песочницу.член как
const string member;
это скопирует данные временного параметра в переменную-член вместо назначения переменной-члена в качестве самого временного параметра.
Технически говоря, эта программа не требуется на самом деле выводить что-либо на стандартный вывод (который является буферизованным потоком для начала).
The
cout << "The answer is: "
немного будет излучать"The answer is: "
на буфер от stdout.тут
<< sandbox.member
бит будет поставлять висячую ссылку вoperator << (ostream &, const std::string &)
, который ссылается неопределенное поведение.из-за этого, ничего не гарантировано случаться. Программа может работать, казалось бы, нормально или может произойти сбой даже без промывки stdout-это означает, что текст "ответ:" не появится на вашем экране.
потому что ваша временная строка вышла из области действия, как только конструктор песочницы вернулся, и стек, занятый им, был исправлен для некоторых других целей.
в целом, вы никогда не должны сохранять ссылки в долгосрочной перспективе. Ссылки хороши для аргументов или локальных переменных, но не для членов класса.
простой ответ : Вы имеете в виду то, что исчез. Следующее будет работать
#include <string> #include <iostream> using namespace std; class Sandbox { public: const string member = " "; Sandbox(const string& n) : member(n) {}//a copy is made }; int main() { Sandbox sandbox(string("four")); cout << "The answer is: " << sandbox.member << endl; return 0; }