No C++
programa a seguir , a modificação de um membro de dados estáticos de uma const
função funciona bem:
class A
{
public:
static int a; // static data member
void set() const
{
a = 10;
}
};
Mas modificar um membro de dados não estático de uma const
função não funciona:
class A
{
public:
int a; // non-static data member
void set() const
{
a = 10;
}
};
Por que uma const
função de membro pode modificar um static
membro de dados?
const
significa que uma função membro de um objeto não pode modificar aquele objeto . Ele pode modificar outros objetos da mesma classe, oustatic
dados, que estão associados à classe, não qualquer instância particular dela. (Oumutable
membros de dados, que foram criados para ser a exceção a esta regra.)Respostas:
É a regra, só isso. E por um bom motivo.
O
const
qualificador em uma função de membro significa que você não pode modificar variáveis de membros quemutable
não sejam destatic
classe.Para oferecer alguma racionalização, o
this
ponteiro em umaconst
função de membro qualificado é umconst
tipo ethis
está inerentemente relacionado a uma instância de uma classe.static
membros não estão relacionados a uma instância de classe. Você não precisa de uma instância para modificar umstatic
membro: você pode fazer isso, no seu caso, por escritoA::a = 10;
.Portanto, em seu primeiro caso, pense
a = 10;
em uma abreviatura paraA::a = 10;
e, no segundo caso, pense nisso como uma abreviação dethis->a = 10;
, que não é compilável porque o tipo dethis
éconst A*
.fonte
this
ponteiro, seria do tipoconst A* const
noconst
caso de.this
é um prvalue do tipo de ponteiro. Prvalues de tipos não-classe nunca são qualificados para cv.De acordo com o padrão C ++ (9.2.3.2 Membros de dados estáticos)
E (9.2.2.1 O indicador this)
E, por último (9.2.2 Funções de membro não estáticas)
Portanto, nesta definição de classe
class A { public: static int a; void set() const { a = 10; } };
o membro de dados estáticos
a
não é um subobjeto de um objeto do tipo de classe e o ponteirothis
não é usado para acessar o membro de dados estáticos. Portanto, qualquer função de membro, constante não estática ou não constante, ou uma função de membro estática pode alterar o membro de dados porque ele não é uma constante.Nesta definição de classe
class A { public: int a; void set() const { a = 10; } };
o membro de dados não estáticos
a
é um subobjeto de um objeto do tipo de classe. Para acessá-lo em uma função de membro, é usada uma sintaxe de acesso de membro desta sintaxe está implícita. Você não pode usar um ponteiro constantethis
para modificar o membro de dados. E o ponteiro this realmente tem tipoconst A *
dentro da funçãoset
porque a função é declarada com o qualificadorconst
. Se a função não tivesse o qualificador, neste caso, o membro de dados poderia ser alterado.fonte
O fato é que, se uma função de membro de uma classe
A
forconst
, o tipo dethis
éconst X*
e, portanto, evita que membros de dados não estáticos sejam alterados (cf, por exemplo, padrão C ++ ):Se
a
for um membro de dados não estático, entãoa=10
é o mesmo quethis->a = 10
, o que não é permitido se o tipo dethis
éconst A*
ea
não foi declarado comomutable
. Assim, uma vez quevoid set() const
faz o tipo dethis
serconst A*
, esse acesso não é permitido.Se
a
for um membro de dados estático, em contraste, entãoa=10
não envolvethis
nada; e enquantostatic int a
por si só não foi declarado comoconst
, declaraçãoa=10
é permitida.fonte
O
const
qualificador em uma função de membro significa que você não pode modificarnon-mutable
,non-static
membros de dados de classe .fonte