2011-07-04 22 views
22

No creo que sea una pregunta duplicada. Hay similares, pero no me ayudan a resolver mi problema.Inicializando la referencia en el constructor C++

Según this, lo siguiente es válido en C++:

class c { 
public: 
    int& i; 
}; 

Sin embargo, cuando hago esto, me sale el siguiente error:

error: uninitialized reference member 'c::i' 

¿Cómo puedo inicializar con éxito hacer i=0 en ¿construcción?

Muchas gracias.

+0

Podría decirnos más acerca de que eres real problema por favor? – fulmicoton

+0

Parece que quieres un puntero. – Mikhail

+0

@Mikhail, [Bjarne Stroustrup] (http://www.stroustrup.com) no le gustan los punteros. Me pregunto qué haría, supongo que no use punteros. – user34660

Respuesta

28

No hay tal cosa como una "referencia de vacío". Usted tiene para proporcionar una referencia en la inicialización del objeto. Ponerlo en lista de inicialización de base de constructores:

class c 
{ 
public: 
    c(int & a) : i(a) { } 
    int & i; 
}; 

Una alternativa sería i(*new int), pero eso sería terrible.

Editar: Para responder a tal pregunta, es probable que sólo quieren i para ser un objeto miembro, no una referencia, por lo que sólo decir int i;, y escribir el constructor ya sea como c() : i(0) {} o como c(int a = 0) : i(a) { }.

+0

"Una alternativa sería i (* nueva int), pero sería terrible". No sería así si el DTOR llama a 'borrar' en ese puntero. – Constantinius

+1

@Constantinius: Sería bastante horrible incluso si recordaras limpiar ... solo piensa en asignaciones, copias, seguridad de excepciones, etc. ... –

+0

Por ejemplo: si tu clase tiene otro miembro de datos que se inicializó después de ' i', o si tiene un código en el cuerpo del constructor, y ese código arroja una excepción, entonces no se llama al destructor y se filtra el recurso. Si una clase tiene un recurso, esa debería ser la * única * cosa que hace. Pero, por supuesto, si estuvieras diseñando una clase para contener un 'int' que solo era propiedad de ese objeto, entonces no usarías un miembro de referencia, usarías un miembro' int', por lo que este "problema" no surgir en la práctica. –

0

referencias tienen que ser inicializado en la creación. Por lo tanto, debe inicializarlo cuando se crea la clase. También debe proporcionar algún objeto legal para referencia.

Tienes que utilizar el inicializador en su constructor:

class c { 
public: 
    c(const int& other) : i(other) {} 
    int& i; 
}; 
+1

Eso es algo terriblemente terrible de hacer. – fulmicoton

+0

Colgando referencia temporal? –

+0

Estaba editando, lo sé :) – Constantinius

4

Aparte de la sintaxis dulce, una característica clave de las referencias es que son bastante seguro de que siempre apuntan a un valor (n valor NULL) .

En el diseño de una API, que obliga al usuario no le enviará NULL. Al consumir una API, sabes sin leer el documento que NULL no es una opción aquí.

-3
template<class T> 
class AVLNode { 

private: 
     T & data; 
public: 
     AVLNode(T & newData) { 
      data = newData; 
     } 
}; 
+1

¿Qué tiene que ver 'AVLNode' o su código con la pregunta? – Pang

+4

Explique cómo su respuesta resuelve el problema, ayudará a todos a comprender su solución con más claridad y para referencia futura. – Aziz

+1

Aunque este código puede ayudar a resolver el problema, no explica _por qué_ y/o_how_ responde la pregunta. Proporcionar este contexto adicional mejoraría significativamente su valor a largo plazo. Por favor [edite] su respuesta para agregar una explicación, incluyendo qué limitaciones y suposiciones se aplican. –

-1

referencia debe ser inicializado ya sea por pasar datos al constructor o asignar memoria del montón si desea inicializar en el constructor por defecto.

class Test 
{ 
    private: 
     int& val; 
     std::set<int>& _set; 
    public: 
     Test() : val (*(new int())), 
       _set(*(new std::set<int>())) { } 

     Test(int &a, std::set<int>& sett) : val(a), _set(sett) { } 
}; 

int main() 
{ 
    cout << "Hello World!" << endl; 
    Test obj; 
    int a; std::set<int> sett; 
    Test obj1(a, sett); 
    return 0; 
} 

Gracias

Cuestiones relacionadas