2011-12-12 15 views
23

Digamos que tenemos un test.cpp de la siguiente manera:¿Por qué no puedo declarar una referencia a un objeto mutable? ("Referencia no puede ser declarada mutable")

class A; 

class B 
{ 
    private: 
     A mutable& _a; 
}; 

Compilación:

$> gcc test.cpp 
test.cpp:6:20: error: reference ‘_a’ cannot be declared ‘mutable’ [-fpermissive] 

Mi gcc:

$> gcc --version 
gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1 
Copyright (C) 2011 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

¿Por qué?

+0

¿Está buscando un puntero? –

+0

Incluso si pudiera hacer esto, sería inútil porque C++ no contiene ninguna sintaxis que pueda cambiar una referencia. Ni siquiera puedes obtener la dirección de memoria de una referencia. Si lo intenta, obtendrá la dirección del objeto al que apunta la referencia. – bames53

+0

Lo siento, hice la pregunta incorrecta. Esta no es una referencia mutable, ¡esta es una referencia a un objeto mutable! (Cambié el título) – Martin

Respuesta

34

No hay ninguna razón para tener un miembro de referencia mutable. ¿Por qué? Debido métodos constantes pueden cambiar el objeto que está referenciado por un miembro de la clase:

class B { 
public: 
    B(int var) : n(var) {}; 
    void Set(int val) const { n = val; } //no error 
    void SetMember(int val) const { m = val; } //error assignment of member `B::m' in read-only structure 
protected: 
    int& n; 
    int m; 
}; 
+0

¡Gracias! Esta es la respuesta que estaba buscando. – Martin

10

Las referencias solo se pueden asignar al construir un objeto, y no se pueden modificar posteriormente. Por lo tanto, hacerlos mutable no tendría ningún significado, por lo que el estándar no lo permite.

+2

Pero una referencia puede ser const o non-const. Así que 'mutable A & a' debería estar bien, ¿no? (No está cerca de un compilador en este momento) –

+2

Pero en este caso, el 'mutable' se aplica al objeto referido, no a la referencia. –

9

Según la norma: [7.1.1 párrafo 8]:

"El especificador mutable se puede aplicar sólo a los nombres de datos de la clase miembros (9.2) y no se pueden aplicar a los nombres const declarada o estático , y no se puede aplicar a los miembros de referencia. "

Así que es ilegal.

2

Esto podría volar tu mente lejos, sino una referencia no es mutable (no se puede hacer para hacer referencia a otro objeto) y el valor de referencia es siempre mutable (a menos que tenga una referencia a const):

#include <iostream> 

struct A 
{ 
    int& i; 
    A(int& n): i(n) {} 
    void inc() const 
    { 
    ++i; 
    } 
}; 

int main() 
{ 
    int n = 0; 
    const A a(n); 
    a.inc(); 
    std::cout << n << '\n'; 
} 

un método const significa que un alto nivel const-calificador se agrega a los miembros. Para una referencia, esto no hace nada (= int & const a;), para un puntero hace el puntero, no la const pointee (= int* const p, no const int* p;).

Cuestiones relacionadas