2010-11-10 3 views
6

Я смотрю на коде следующего вида:значения инициализация константного элемента ссылка

class foo 
{ 
    public: 
    foo() {} 

    //... 
}; 

class bar 
{ 
    public: 
    bar() : ref() {} 

    private: 
    const foo &ref; 
}; 

инициализирует ссылку, используя временную, таким образом, правильно? Я знаю, что можно инициализировать ссылку на const, которая является локальной переменной с временным, и что это увеличивает время жизни временного, например.

const foo &tmp = funcThatReturnsByValue(); //OK 

Однако один из ответов на соответствующие initialize reference in initialization list предполагает, что существует разница между «короткоживущим» и «долгоживущим» ссылкой, и что при инициализации ref как указано выше, является неопределенным поведением (хотя и ref является ссылкой const).

12.2.5 в стандарте, в частности, говорится: «Временная привязка к ссылочному элементу в конструкторе-инициализаторе конструктора сохраняется до тех пор, пока конструктор не выйдет». Это описывает эту ситуацию?

+0

Не могли бы вы исправить свой код, чтобы на самом деле он был временным? –

+0

ref() не связывает ref с временным экземпляром foo? Извините, если моя терминология неточна ... Я делаю все возможное, чтобы понять этот фрагмент кода. – user168715

+0

Возможно, этот комментарий бесполезен (я не знаю контекста, который вы смотрите на этот код), но проблема исчезает, если 'ref' является указателем. Дело в том, что ссылки не могут быть инициализированы значением, но указатели могут (они получают нуль-инициализацию). Более того, большинство компиляторов (по крайней мере, MSVC) выдает предупреждение о невозможности создания оператора присваивания по умолчанию. В качестве ориентира, когда вы хотите использовать элемент ссылки, вы хотите, чтобы на самом деле указатель ... –

ответ

4

Этот код плохо сформирован. Вы не можете инициализировать по умолчанию или значение инициализировать ссылку.

Если у вас на самом деле есть выражение внутри ref(), тогда да, 12.2.5 будет применяться, и временное будет уничтожено при выходе из конструктора.

+1

Вы бы подумали, но я не могу получить GCC 4.3.4, чтобы на самом деле это сделать. –

1

Я предполагаю, что вы хотите сделать, это:

bar() : ref(foo()) {} 

, но не наивно думать, что время жизни временно продлевается до тех пор, пока это ссылка на него. Нет, на самом деле это не так. Итак, независимо от того, const или нет, вы можете инициализировать ссылку нормальным объектом.

2

Ваш пример не создает временный - для этого вам нужно изменить на:

bar() : ref(foo()) {} 

Теперь вы связываете ссылку на временный, и что временный объект будет уничтожен в конце конструктора. Ваша ссылка будет недействительной, и это не хорошая вещь.

Смежные вопросы