Dans ce qui suit C++
programme, modifier un membre de données statique à partir d'une fonction const
fonctionne correctement:
class A
{
public:
static int a; // static data member
void set() const
{
a = 10;
}
};
Mais modifier une membre de données non statique depuis une fonction const
ne fonctionne pas:
class A
{
public:
int a; // non-static data member
void set() const
{
a = 10;
}
};
Pourquoi une fonction membre const
peut-elle modifier un membre data static
?
C'est la règle, c'est tout. Et pour une bonne raison.
Le qualificatif const
d'une fonction membre signifie que vous ne pouvez pas modifier les variables de membre de classe non -mutable
non -static
.
Pour offrir une certaine rationalisation, le pointeur this
dans une fonction membre qualifiée const
est un type const
et this
est intrinsèquement lié à un - instance d'une classe. static
les membres ne sont pas liés à une instance de classe. Vous n'avez pas besoin d'une instance pour modifier un membre static
: vous pouvez le faire, dans votre cas, en écrivant A::a = 10;
.
Donc, dans votre premier cas, pensez à a = 10;
comme raccourci pour A::a = 10;
et dans le second cas, considérez cela comme un raccourci pour this->a = 10;
, qui n'est pas compilable car le type de this
est const A*
.
Selon la norme C++ (9.2.3.2 Membres de données statiques)
1 Un membre de données statique est ne fait pas partie des sous-objets d'une classe ...
Et (9.2.2.1 Le pointeur this)
1 Dans le corps d'une fonction membre non statique (9.2.1), le mot-clé est une expression prvalue dont la valeur est l'adresse de l'objet pour lequel la fonction est appelée. Le type de ceci dans une fonction membre d'une classe X est X *. Si la fonction membre est déclarée const, son type est const X *, ...
Et enfin (9.2.2 Fonctions membres non statiques)
3 ... si name lookup (3.4) résout le nom dans l'expression id en un membre non typé non statique d'une classe C, et si l'expression id est potentiellement évaluée ou si C est X ou une classe de base de X, l’expression id est transformée en une expression d’accès aux membres de la classe (5.2.5) en utilisant (* this) (9.2.2.1) comme expression postfixe située à gauche de. opérateur.
Donc dans cette définition de classe
class A
{
public:
static int a;
void set() const
{
a = 10;
}
};
le membre de données statique a
n'est pas un sous-objet d'un objet du type classe et le pointeur this
n'est pas utilisé pour accéder au membre de données statique. Ainsi, toute fonction membre, constante non statique ou non statique, ou une fonction membre statique peut modifier le membre de données car ce n'est pas une constante.
Dans cette définition de classe
class A
{
public:
int a;
void set() const
{
a = 10;
}
};
le membre de données non statique a
est un sous-objet d'un objet du type classe. Pour y accéder dans une fonction membre, on utilise soit une syntaxe d'accès membre, de cette syntaxe soit implicite. Vous ne pouvez pas utiliser un pointeur constant this
pour modifier le membre de données. Et le pointeur est en effet de type const A *
dans la fonction set
car la fonction est déclarée avec le qualificatif const
. Si la fonction n'avait pas de qualificatif dans ce cas, le membre de données pourrait être modifié.
Le fait est que si une fonction membre d'une classe A
est const
, le type de this
est _const X*
_ et empêche ainsi les données non statiques membres d'être altérés (cf, par exemple, norme C++ ):
9.3.2 Le pointeur this [class.this]
Dans le corps d'une fonction membre non statique (9.3), le mot clé this est une expression prvalue dont la valeur est l'adresse de l'objet pour lequel la fonction est appelée. Le type de ceci dans une fonction membre d'une classe X est X *. Si la fonction membre est déclarée const, son type est const X *, ...
Si a
est un membre de données non statique, alors _a=10
_ est identique à _this->a = 10
_, ce qui n'est pas autorisé si le type de this
est _const A*
_ et a
n'a pas été déclaré comme mutable
. Ainsi, puisque void set() const
rend le type de this
étant _const A*
_, cet accès n'est pas autorisé.
Si a
est un membre de données statique, par contre, alors _a=10
_ n'implique pas du tout this
; et tant que _static int a
_ seul n'a pas été déclaré comme const
, l'instruction _a=10
_ est autorisée.
Le qualificatif const
sur un fonction membre signifie que vous ne pouvez pas modifier non-mutable
, non-static
membres de données de classe.