Appeler un non-const fonction de membre à partir d'une fonction membre const
Je voudrais savoir si ses possible d'appeler un non-const fonction de membre à partir d'une fonction membre const. Dans l'exemple ci-dessous donne d'Abord une erreur de compilation. Je comprends pourquoi il donne une erreur, je voudrais savoir si il existe un moyen de le contourner.
class Foo
{
const int& First() const
{
return Second();
}
int& Second()
{
return m_bar;
}
int m_bar;
}
Je n'ai pas vraiment envie de discuter de la sagesse de faire cela, je suis curieux de savoir si c'est encore possible.
- Vous n'êtes pas le premier: stackoverflow.com/questions/856542/...
- merci Till, qui n'est pas venu dans ma recherche
Vous devez vous connecter pour publier un commentaire.
Puis pleurer, doucement.
Il est possible:
Je ne recommanderais pas cela; c'est moche et dangereux (toute utilisation de
const_cast
est dangereux).Il est préférable de déplacer autant de fonctionnalités courantes que vous pouvez dans des fonctions d'assistance, puis avoir votre const et non const fonctions de membres de chacun de faire aussi peu de travail que nécessaire.
Dans le cas d'un simple accesseur de ce genre, il est tout aussi facile à
return m_bar;
à la fois des fonctions qu'il est d'appeler une fonction de l'autre.int& Second()
enint& Second() const
. Le non-const
fonctions de membre n'auront aucun problème à l'appel deSecond()
, mais maintenant, leconst
fonctions de membre sera en mesure de les appeler, c'est sans aucun jiggery-pokery, trop.m_bar
comme unmutable int
. @Fred Larson recommandation est assez bonne, mais la direction qu'il mène d'écriture de tous les bienheureux accesseur deux fois, une foisconst
modifiés et une fois n'est pas - n'est pas si joyeux.return m_bar;
dans les deux d'entre eux n'est généralement pas trop de un fardeau supplémentaire.Par la définition de
const
, une fonction ne doit pas modifier l'état d'un objet. Mais si elle appelle une autre non-const membre, l'état de l'objet peut se changer, il est donc rejetée.Je sais que vous avez dit que vous ne vouliez pas l'entendre à ce sujet, mais je pense qu'il est important, pour d'autres qui se produisent sur la question.
La restriction de const méthodes membres sont venus de la compilation. Si vous pouvez tromper le compilateur, alors oui.
Ce fait abolit le but de const fonction de membre, il est donc préférable de ne pas le faire lors de la conception d'une nouvelle classe. C'est pas mal de savoir qu'il y a un moyen de le faire,en particulier, il peut être utilisé comme un travail autour de ces vieux de la classe qui n'a pas été bien conçu sur le concept de fonction membre const.
Surcharge sur
const
:Vous pouvez ajouter cette méthode et de conserver l'original de non-const version.
les itérateurs sont similaires dans le présent et de faire une étude intéressante.
const itérateurs sont souvent la base pour le "non const' itérateurs, et vous trouverez souvent
const_cast<>()
ou C style jette utilisé pour rejeter const de la classe de base avec les accesseurs de l'enfant.Edit:
Commentaire
Ce serait généralement le mauvais héritage de la structure (si votre de dire ce que je pense que vous êtes), la raison étant que les enfants ne devraient pas être moins restrictives que les parents.
disons que vous avez eu un algorithme de prendre votre zip itérateur, serait-il approprié de passer un const itérateur pour un non const ?
si vous aviez un const conteneur, ne pouvait demander pour un const itérateur, mais alors la const itérateur est dérivé à partir d'un itérateur, alors il suffit d'utiliser les fonctionnalités du parent non const accès.
Voici un rapide aperçu de suggestions de l'héritage à la suite de la traditionnelle modèle stl
const_cast
et rend le code plus facile à lire.template <typename T> class iterator_impl
et puis dans le conteneur à l'aide de fournir untypedef iterator_impl<const T> const_iterator
ettypedef iterator_impl<T> iterator
. Vous pouvez ensuite, à l'intérieur de laiterator_impl
modèle extrait de la constness deT
et de définir tous les types de retour et des pointeurs et de telle manière appropriée. Est-ce que vous cherchez? (Je veux juste m'assurer que je comprends exactement ce dont vous avez besoin).J'ai essayé d'appeler un non-const fonction membre qui a été hérité, mais qui était en fait const en raison de l'API, j'ai été à l'aide. Finalement, j'ai installé sur une autre solution: re-négocier l'API de sorte que la fonction que j'ai hériter est correctement const.
Il ne sera pas toujours possible de négocier des modifications à d'autres fonctions, mais de le faire quand c'est possible semble plus propre et plus agréable que de devoir utiliser const_cast et il profite à d'autres utilisateurs en tant que bien.