2009-11-09 30 views

Respuesta

33

Se debe inicializar una referencia para hacer referencia a algo; no puede referirse a nada, por lo que no puede construir por defecto una clase que contenga uno (a menos que, como otros sugieren, defina un valor "nulo" global). Se necesita un constructor que se le da la Div para referirse a:

explicit A(Div &d) : divs(d) {} 

Si usted quiere que sea capaz de ser "nulo", entonces necesita un puntero, no una referencia.

+1

En general, no es cierto que no pueda construir una clase por defecto con un miembro de referencia. Por ejemplo, la referencia puede vincularse a un objeto declarado en el ámbito del espacio de nombres (objeto "global", en palabras más simples). – AnT

+1

Como se señaló, puede hacer un constructor predeterminado si usa una variable predefinida (como en mi ejemplo a continuación). –

+2

Ambos son correctos. Sin embargo, desaconsejaría usar un valor "nulo" global; no puede ser const, por lo que el comportamiento predeterminado sería usar un objeto global que cualquier otra instancia de la clase pueda cambiar sin previo aviso. –

8

Por un lado, se puede' t tiene una referencia NULL. Como segundo, todas las referencias de variables en una clase deben inicializarse en el momento de la construcción.

+0

cómo lo corrijo? – aajkaltak

+0

@varun: necesita inicializar su referencia a una instancia de objeto válida en el momento de la construcción (es decir, en su constructor). – jldupont

+1

@varun: tenga en cuenta que puede buscar un puntero si eso le hace la vida más fácil ... o refactorizar. – jldupont

5

En "inglés": una referencia se refiere a algo. No puede hacer referencia a nada (nulo). Es por eso que las referencias son más seguras que los punteros.

+5

No solo en inglés. Lo mismo es cierto en C++. – jalf

+1

lol, quise decir "la regla de C++ escrita en inglés común" ;-) – Abel

12

divs es una referencia, no un puntero. No puede establecerlo en NULL, tiene que apuntar a un objeto real de algún tipo. Lo mejor que puede hacer aquí es probablemente definir una instancia estática/global de Div que arbitrariamente defina como la "Div nula" (establezca su valor en algo que probablemente nunca use) e inicialice div a eso. Algo como esto:

struct Div 
{ 
    int i; 
    int j; 
}; 

Div NULL_DIV = { INT_MAX, INT_MAX }; 

class A 
{ 
    public: 
      A(); 
      Div& divs; 
}; 


A::A() : divs(NULL_DIVS) 
{ 
} 

O, como alternativa, simplemente convierta a los divs en un puntero en lugar de una referencia.

* Tenga en cuenta que usted no puede utilizar una referencia constante a menos que desecharon la constness ya que por defecto el compilador no permitirá asignar una referencia a un cosnt ref no constante.

+0

estás inicializando la referencia no const con el objeto const. ¿Compila? – Arkadiy

+0

Ah, buena captura, no, no. Actualizaré la respuesta. –

3

Las referencias tienen que hacer referencia a algo. No existe una referencia nula en el lenguaje C++. Si el miembro no puede tener un valor, entonces debe ser un puntero, o un boost::optional o algún tipo así.

Una referencia debe ser inicializado para hacer referencia a un objeto válido.

3

Tenga en cuenta que una vez que se inicia una referencia al punto a algo, no se puede alterar para que apunte a otra cosa. Si este no es el comportamiento deseado, entonces debe usar un puntero o una copia del objeto en su lugar.

1

Como se observó en otros mensajes, referencias (Div &) no puede ser nulo. Entonces, el cambio más directo que puede hacer es proporcionar una referencia en el constructor e inicializar su miembro de referencia.De esta manera,

class A 
{ 
    public: 
      A(Div& inDivs); 
      Div& divs; 

}; 

public A::A(Div& inDivs) 
: divs(inDivs) 
{} 
3

El mensaje compilador es uno de esos mensajes que no tienen sentido desde el punto de vista del lenguaje, pero revelan el funcionamiento interno del compilador, la secuencia en la que sus obras lógicas internas.

En su caso está utilizando un valor r (NULL) para inicializar una referencia. Cuando se permite dicha inicialización, el valor r se convierte en un objeto temporal, al que se vinculará la referencia. Entonces, el compilador se dio cuenta de inmediato y le informó sobre el hecho con un mensaje de diagnóstico.

En realidad, el truco como ese solo está permitido para las referencias const, por lo que su código está roto, ya que la referencia no es const en nuestro caso. Además, una referencia struct, como la de su código, no se puede inicializar con NULL rvalue (que tiene un tipo integral), por lo que también se rompe por ese motivo.

El mensaje del compilador es bastante confuso. El texto del mensaje parece implicar que es ilegal inicializar referencias de miembros con objetos temporales. De hecho, esto es legal en C++ (una vez que se resuelven los problemas anteriores), aunque no tiene sentido. Sin embargo, creo que, una vez que el código mal formada se acompaña de al menos algunos mensaje de error, debería estar bien para todo el mundo ...

2

Así de simple:

Una referencia no puede ser NULL.

1
class A 
{ 
    Div & ref(Div div) { return div; } 
    public: 
     A() : divs(ref(Div())) {}; 
     Div& divs; 
}; 
+0

Aunque este código puede responder a la pregunta, proporcionar un contexto adicional con respecto a por qué y/o cómo responde la pregunta mejoraría significativamente su valor a largo plazo. Por favor, edite su respuesta para agregar alguna explicación. – gevorg

0

que sugeriría:

class A{ 
    std::deque<object*>& que = *(std::deque<object*> *)0; 
    // ... 
    // Of course `que` is to be assigned valid deque before using it - just like pointers... 
}; 
+1

Agregue un texto con su código que describa por qué lo sugeriría. La pregunta ya tiene una respuesta aceptada, por lo que una explicación de por qué tu respuesta es válida también/mejor, sería de gran ayuda. – Banana

+0

Lo siento, no entendí por qué tengo que explicar el motivo para usar esta solución, excepto que muestra que funciona. – Bretzelus

+0

Podría funcionar en algunas implementaciones, pero no es conforme. Si desea un puntero, simplemente use un puntero, en lugar de tales chanchullos que violan por completo la intención de las referencias. –

Cuestiones relacionadas