una miembros funciones funcion estaticos estaticas estatica ejemplos clase c++ function c++11 static const

c++ - funciones - miembros estaticos de una clase java



¿Por qué una función miembro const puede modificar un miembro de datos estático? (4)

En el siguiente programa C++ , la modificación de un miembro de datos estáticos desde una función const funciona bien:

class A { public: static int a; // static data member void set() const { a = 10; } };

Pero modificar un miembro de datos no estático desde una función const no funciona:

class A { public: int a; // non-static data member void set() const { a = 10; } };

¿Por qué una función miembro const puede modificar un miembro de datos static ?


De acuerdo con el estándar C ++ (9.2.3.2 Miembros de datos estáticos)

1 Un miembro de datos estáticos no es parte de los subobjetos de una clase ...

Y (9.2.2.1 El este puntero)

1 En el cuerpo de una función miembro no estática (9.2.1), la palabra clave this es una expresión prvalue cuyo valor es la dirección del objeto para el que se llama la función. El tipo de esto en una función miembro de una clase X es X *. Si la función miembro se declara const, el tipo de esto es const X * , ...

Y por fin (9.2.2 Funciones miembro no estáticas)

3 ... si la búsqueda de nombre (3.4) resuelve el nombre en la expresión id a un miembro no estático no tipo de alguna clase C, y si la expresión id se evalúa potencialmente o C es X o una clase base de X, la expresión id se transforma en una expresión de acceso de miembro de clase (5.2.5) usando (* this) (9.2.2.1) como la expresión postfix a la izquierda de. operador.

Así en esta definición de clase

class A { public: static int a; void set() const { a = 10; } };

el miembro de datos estáticos a no es un subobjeto de un objeto del tipo de clase y el puntero no se usa para acceder al miembro de datos estáticos. Por lo tanto, cualquier función miembro, constante no estática o no constante, o una función miembro estática puede cambiar el miembro de datos porque no es una constante.

En esta definición de clase

class A { public: int a; void set() const { a = 10; } };

el miembro de datos no estático a es un subobjeto de un objeto del tipo de clase. Para acceder a él en una función miembro, se utiliza una sintaxis de acceso de miembro de esta sintaxis. No puede usar un puntero constante para modificar el miembro de datos. Y el puntero que esto es tiene tipo const A * dentro del set funciones porque la función se declara con el calificador const . Si la función no tuviera el calificador en este caso, el miembro de datos podría cambiarse.


El calificador const en una función miembro significa que no puede modificar miembros de datos de clase non-static non-mutable .


Es la regla, eso es todo. Y por buenas razones.

El calificador const en una función miembro significa que no puede modificar las variables miembro de clase no static no mutable .

Para ofrecer una cierta racionalización, el puntero this en una función miembro calificada const es un tipo const , y this está inherentemente relacionado con una instancia de una clase. static miembros static no están relacionados con una instancia de clase. No necesita una instancia para modificar un miembro static : puede hacerlo, en su caso, escribiendo A::a = 10; .

Entonces, en su primer caso, piense en a = 10; como taquigrafía para A::a = 10; y en el segundo caso, piense en esto como una abreviatura de this->a = 10; , que no es compilable ya que el tipo de this es const A* .


La cuestión es que si una función miembro de una clase A es const , entonces el tipo de this es const X* , y por lo tanto evita que se alteren los miembros de datos no estáticos (cf, por ejemplo, el estándar C ++ ):

9.3.2 El puntero this [class.this]

En el cuerpo de una función miembro no estática (9.3), la palabra clave es una expresión de valor cuyo valor es la dirección del objeto para el que se llama la función. El tipo de esto en una función miembro de una clase X es X *. Si la función miembro se declara const, el tipo de esto es const X *, ...

Si a es un miembro de datos no estático, a=10 es lo mismo que this->a = 10 , lo que no está permitido si el tipo de this es const A* y a no se ha declarado como mutable . Por lo tanto, dado que void set() const hace que el tipo de this sea const A* , este acceso no está permitido.

Si a es un miembro de datos estáticos, en contraste, entonces a=10 no implica this en absoluto; y mientras static int a por sí mismo no se haya declarado como const , se permite la instrucción a=10 .