Un collègue a posé des questions sur un code comme celui-ci qui avait à l'origine des modèles à l'origine.
J'ai supprimé les modèles, mais la question principale reste: pourquoi cela compilait-il OK? P>
#include <iostream>
class X
{
public:
void foo() { std::cout << "Here\n"; }
};
typedef void (X::*XFUNC)() ;
class CX
{
public:
explicit CX(X& t, XFUNC xF) : object(t), F(xF) {}
void execute() const { (object.*F)(); }
private:
X& object;
XFUNC F;
};
int main(int argc, char* argv[])
{
X x;
const CX cx(x,&X::foo);
cx.execute();
return 0;
}
5 Réponses :
Dans ce contexte Si vous changez votre Définition de la classe à ne pas utiliser de référence: p> Vous obtenez l'erreur que vous attendez. p> p> objet code> est une référence à un x code> em>, pas un référence à un const x code> em>. Le qualificatif const code> serait appliqué sur le membre (c'est-à-dire la référence, mais les références ne peuvent pas être const code>), non à l'objet référencé.
Néanmoins, avec const code> -methods, il ne faut-il que appeler const code> -methods sur les objets membres, n'est-ce pas?
Le membre est la référence, pas l'objet référencé.
Le Pour illustrer: P> const code> NESS de exécuter () code> n'affecte que le pointeur code> de la classe. Il rend le type de ceci code> A const t * code> au lieu de t * code>. Ce n'est pas un "profond", cependant - cela signifie seulement que les membres eux-mêmes ne peuvent pas être changés, mais tout ce qu'ils indiquent ou font encore référence. Votre membre objet code> ne peut déjà pas être modifié, car les références ne peuvent pas être re-assises pour signaler quoi que ce soit d'autre. De même, vous n'êtes pas changer em> le membre F code>, il suffit de la désirer en tant que pointeur de fonction membre. Donc, tout cela est autorisé, et d'accord pouvez. Vous pouvez toujours appeler des fonctions de membre const sur les objets constants, donc pas de changement là-bas. P> class MyClass
{
public:
/* ... */
int* p;
void f() const
{
// member p becomes: int* const p
*p = 5; // not changing p itself, only the thing it points to - allowed
p = NULL; // changing content of p in const function - not allowed
}
};
Il est important de noter que vous pouvez essentiellement traiter un t & code> comme t * cons code>. Quoi qu'il en soit, je conviens que la propagation peu profonde de const code> est étrange, mais nous avons ensuite une copie peu profonde par défaut ...
L'instance par la logique alternative, une méthode objet code> de classe x code> n'est pas Const. Il est simplement référencé par un objet qui est constitué. La const-ness s'applique récursivement aux sous-observations, pas à des objets référencés. P>
const code> ne serait pas en mesure de modifier rien em>. Qui s'appelle une "fonction pure", un concept qui n'existe pas dans la norme actuelle C ++. P>
Vous appelez Etant donné que foo code> sur objet code>, pas sur ceci code>. p>
objet code> est déclaré sous la forme d'un x & code>, dans une constante CX, il est en fait un x & const code> (qui n'est pas le même que const x & code>) vous permettant d'appeler des méthodes non constituées dessus. P>
J'ai l'impression que vous auriez dû mentionner "& const" est absurde dans le langage, car il n'existe pas de "redevance de référence".
Une manière utile de penser à ce sujet pourrait être que votre objet X n'est pas membre de CX du tout. P>
Vous pourriez y penser comme ça, mais peu importe si c'est ou non. Cette classe pourrait avoir une instance x ( objet code>) en tant que membre et également un élément de référence pour faire référence à cela. Alors vous constaterez que vous ne pouvez pas faire (objet. * F) (); code>, mais peut toujours faire (référence. * F) (); code> même si Il fait référence exactement à la même chose que est B> membre de CX.