2012-02-15 12 views
5

Con el fin de frenar el argumento pasando en los comentarios de an answer I gave recently, me gustaría algunas respuestas constructivas a las siguientes preguntas:La vida útil de una referencia con respecto a su objetivo

  1. ciclo de vida tiene una referencia distinta del objeto al que se refiere? ¿Es una referencia simplemente un alias para su objetivo?
  2. ¿Puede una referencia sobrevivir a su objetivo en un programa bien formado sin resultar en un comportamiento indefinido?
  3. ¿Se puede hacer una referencia para referirse a un nuevo objeto si se reutiliza el almacenamiento asignado para el objeto original?
  4. ¿El siguiente código demuestra los puntos anteriores sin invocar un comportamiento indefinido?

Código de ejemplo por Ben Voigt y simplificado (ejecutarlo en ideone.com):

#include <iostream> 
#include <new> 

struct something 
{ 
    int i; 
}; 

int main(void) 
{ 
    char buffer[sizeof (something) + 40]; 
    something* p = new (buffer) something; 
    p->i = 11; 
    int& outlives = p->i; 
    std::cout << outlives << "\n"; 
    p->~something(); // p->i dies with its parent object 
    new (p) char[40]; // memory is reused, lifetime of *p (and p->i) is so done 
    new (&outlives) int(13); 
    std::cout << outlives << "\n"; // but reference is still alive and well 
            // and useful, because strict aliasing was respected 
} 
+0

Esta es una gran cantidad de preguntas, cada una de las cuales requiere bastantes citas de redacción estándar para responder correctamente (dada la naturaleza de la pregunta, creo que espera que las citas estándar sean las respuestas correctas). Es/podría/ser más útil si nos concentráramos en uno de ellos, y si es útil en ese contexto solo responderemos a los demás ... – PlasmaHH

+0

Estoy de acuerdo. Por favor, una pregunta por pregunta. Y encontrará que las preguntas han sido respondidas antes. –

+0

Además, esa muestra de código tiene demasiado en marcha. Haga una pequeña caja de prueba. –

Respuesta

9

ciclo de vida tiene una referencia distinta del objeto se refiere a? ¿Es una referencia simplemente un alias para su objetivo?

Una referencia tiene su propio tiempo de vida:

int x = 0; 
{ 
    int& r = x; 
}  // r dies now 
x = 5; // x is still alive 

A ref-a-const adicionalmente puede extender la vida útil de su árbitro:

int foo() { return 0; } 
const int& r = foo(); // note, this is *not* a reference to a local variable 
cout << r;    // valid; the lifetime of the result of foo() is extended 

aunque esto no es sin salvedades:

Una referencia a const solo extiende la vida o f un objeto temporal si la referencia es a) local yb) está vinculado a un valor prvejo cuya evaluación crea dicho objeto temporal. (Por lo tanto, no funciona para los miembros o referencias locales que están vinculados a valores x). Además, las referencias de valores no const extienden la vida útil de la misma manera. [@FredOverflow]


Puede una referencia sobrevivir a su objetivo en un programa bien formada sin resultar en un comportamiento indefinido?

Claro, mientras no lo uses.


Se puede hacer una referencia para hacer referencia a un objeto nuevo si el almacenamiento asignado para el objeto original se vuelve a utilizar?

Sí, bajo algunas condiciones:

[C++11: 3.8/7]: Si, después de que el tiempo de vida de un objeto ha terminado y antes de que el almacenamiento de la que el objeto ocupada se reutiliza o se libera, un nuevo objeto se crea en el almacenamiento la ubicación que ocupó el objeto original, un puntero que apunta al objeto original, una referencia que hace referencia al objeto original, o el nombre del objeto original se referirá automáticamente al nuevo objeto y, una vez que el tiempo de vida del nuevo objeto iniciado, se puede usar para manipular el nuevo objeto, si:

  • el almacenamiento para el nuevo objeto se superpone con exactitud la ubicación de almacenamiento que el objeto original ocupada, y
  • el nuevo objeto es del mismo tipo que el objeto original (ignorando los de nivel superior CV-calificadores) y
  • el tipo del objeto original no está const-calificado, y, si un tipo de clase, no contiene ningún miembro de datos no estáticos cuyo tipo es const-calificado o un tipo de referencia, y
  • el objeto original era un la mayoría de los objetos derivados (1.8) de tipo T y el nuevo objeto es el objeto más derivado de tipo T (es decir, no son subobjetos de clase base).

que hace el código siguientes muestran los puntos anteriores sin necesidad de invocar un comportamiento indefinido?

Tl; dr.

+0

Una referencia a const solo extiende la vida útil de un objeto temporal si la referencia es a) local yb) está vinculada a un valor pr con una evaluación que crea dicho objeto temporal. (Por lo tanto, no funciona para los miembros o referencias locales que están vinculados a valores x). Además, las referencias de valores no const extienden la vida útil de la misma manera. – fredoverflow

+0

@FredOverflow: ¡Ta! –

5
  1. Sí. Por ejemplo, las referencias no estáticas locales tienen una duración de almacenamiento automática y una vida útil correspondiente y pueden referirse a objetos que tienen una vida útil más larga.

  2. Sí, las referencias colgantes son un ejemplo. Siempre que tales referencias no se usen en ninguna expresión cuando se vuelven inestables, están bien.

  3. Hay una regla especial en la cláusula 3 sobre este caso. Los nombres de objetos, punteros y referencias se refieren automáticamente al nuevo objeto que reutiliza el almacenamiento en condiciones restringidas. Creo que es al final de 3.8. Alguien que tenga la especificación a mano, complete la referencia correcta aquí.

Cuestiones relacionadas