2010-11-10 14 views
6

Estoy buscando en el código de la siguiente forma:valor de inicialización de un miembro const refiero

class foo 
{ 
    public: 
    foo() {} 

    //... 
}; 

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

    private: 
    const foo &ref; 
}; 

se está iniciando una referencia temporal utilizando una de esta manera correcta? Sé que es posible inicializar una referencia constante que sea una variable local con una temporal, y que al hacerlo amplíe la vida útil del temporal, p.

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

Sin embargo, una de las respuestas a la relacionada initialize reference in initialization list sugiere que hay una diferencia entre, y que al inicializar ref que el anterior es un comportamiento indefinido "de larga duración" referencias "de corta duración" y (a pesar de que ref es una referencia const).

12.2.5 en el estándar dice, en parte, "Un enlace temporal a un miembro de referencia en el inicializador de códigos del constructor persiste hasta que el constructor sale". ¿Eso es describir esta situación?

+0

¿Podría arreglar su código para que realmente implique un temporal? –

+0

ref() no enlaza ref a una instancia temporal de foo? Lo siento si mi terminología es imprecisa ... Hago mi mejor esfuerzo para comprender este fragmento de código. – user168715

+0

Quizás este comentario no valga la pena (no conozco el contexto en el que está viendo este código), pero el problema desaparece si 'ref' es un puntero. El punto es que las referencias no se pueden inicializar en valores, pero los punteros pueden (se inicializan en cero). Además, la mayoría de los compiladores (al menos MSVC) emiten una advertencia por no poder generar un operador de asignación predeterminado. Como guía, cuando quiera un miembro de referencia, realmente quiere un puntero ... –

Respuesta

4

Este código está mal formado. No puede inicializar por defecto o valorizar inicializar una referencia.

Si realmente tiene una expresión dentro de ref(), entonces sí, 12.2.5 se aplicaría y el temporal se destruiría cuando el constructor salga.

+1

Lo pensarías, pero no puedo lograr que GCC 4.3.4 realmente lo haga. –

1

Creo que lo que quiere hacer es:

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

pero no creo que ingenuamente que el tiempo de vida de un temporal se extiende hasta que haya una referencia a él. No, en realidad no lo es. Entonces, ya sea const o no, debes inicializar la referencia con un objeto normal.

2

Su ejemplo no es la creación de un temporal - para hacer eso tiene que cambiar a:

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

Ahora estás vinculante la referencia a un temporal, y ese objeto temporal será destruido al final del constructor Su referencia será inválida, y eso no es algo bueno.

Cuestiones relacionadas