question de newbie: c++ const non-const de conversion
Je suis vraiment agacé par const
mot-clé de ces jours, que je ne suis pas assez familier avec elle. J'ai eu un vecteur qui stocke toutes les pointeurs const comme vector<const BoxT<T> *> *Q_exclude
, et dans le constructeur d'une autre classe, j'ai besoin d'un élément dans cette file d'attente pour être transmis en tant que paramètre et l'attribuer à un non-const membre. Ma question est:
Comment assigner une variable const à un non-const variable? Je sais que ce n'est pas logique parce que, après tout, const est un const, et ne doit pas être modifié par n'importe quel moyen. Mais ce gênant variable membre doit VRAIMENT être modifiées au cours du processus! Je pourrais aussi modifier le type de données dans le vecteur d'être non-const, mais ce serait trop de travail. Ou personne ne sait comment éviter ce genre de situation?
- Pourquoi avez-vous stocker des pointeurs vers les const, si vous souhaitez modifier les objets qu'ils point?
- Peut-être poster un peu de code... mais comme RMF dit, cela ressemble à des malheureux de la conception.
- "Mais qu'ennuyeux variable membre doit VRAIMENT être modifiées au cours du processus!" Alors, pourquoi avez-vous en faire un
const
variable de membre? Si vous vous trouvez avoir besoin de modifier quelque chose qui estconst
, alors cela indique un problème de conception. Soit vous ne devez pas modifier, ou vous devez repenser si c'est vraimentconst
à tous. - Il y a peut-être un peu d'un problème avec C++: vous pourriez voulez que les données soient const dans certaines fonctions et non-const dans d'autres. Cependant, avec
vector
c'est soit tout ou rien. - De toute façon, vous n'avez pas besoin de faire tout ce que vous pouvez const. IMO, si vous pouvez passer const références (pour la performance), c'est assez. - Magasin de non-
const
éléments, puis passer l'ensemble de vecteurs d'const
dans les contextes où l'accès à l'élément ne doit pas être sujette au changement. Simples! - pas tout à fait, car un
const vector<T*>
encore vous permet de modifier les referands de ses éléments. L'appelant peut accepter de signer une convention avec vous, qu'un const vecteur de pointeurs signifie "ne pas modifier le referands soit", mais le type de système n'est pas dans le deal. Vous pouvez utiliser un adaptateur pour le but (si vous passez plages d'itérateur paires, plutôt que de passer l'ensemble du vecteur, c'est pas que beaucoup de travail pour écrire l'adaptateur). - Ah, oui, parce que vous obtenez un
T* const
. Je suis avec vous maintenant. Eh bien, ce n'est pas tellement un défaut de conception comme un fait d'indirection que certaines personnes n'aiment pas l'accepter. 🙂 D'ailleurs, stocke des pointeurs dans unvector
est faible. - Ce que je voulais dire par "tout ou rien" est ce que vous avez suggéré. Que faire si je veux une fonction pour être en mesure de modifier le conteneur, mais pas les éléments existants? - Je crois que cela ne peut pas être vraiment atteint, donc vers le bas avec
const
. C'est pratique si le langage permet de bien, mais d'autres langues sont bien sans const, donc vous serez très bien sans aussi. - Vous pouvez stocker
T const*
(ce qui n'est pas le même queT* const
). Mais oui, vous pouvez ne jamais modifier des éléments existants. Franchement je pense que ce "tout ou rien"ness fait sens, plutôt que d'être "un peu d'un problème avec C++"; il devrait être en place pour le conteneur de décider de la mutabilité des choses à l'intérieur, pas une fonction arbitraire qui veut l'utiliser.
Vous devez vous connecter pour publier un commentaire.
Vous pouvez attribuer un
const
objet d'un non-const
objet de l'amende juste. Parce que vous êtes copie et donc la création d'un nouvel objet,const
ness n'est pas violé.Comme suit:
C'est différent si vous souhaitez obtenir un pointeur ou une référence à l'original,
const
objet:Vous pouvez utiliser
const_cast
de pirater à travers le type de sécurité si vous devez vraiment, mais rappelez-vous que vous êtes en train de faire exactement cela: se débarrasser de la sécurité de type. C'est encore pas défini de modifiera
parb
dans l'exemple ci-dessous:Bien qu'il se compile sans erreurs, tout peut arriver, y compris l'ouverture d'un trou noir ou le transfert de tous vos économies durement gagnées dans mon compte bancaire.
Si vous êtes arrivé à ce que vous pensez est une exigence pour ce faire, je serais de toute urgence revoir votre conception parce que quelque chose est très mal avec elle.
La modification d'une constante de type qui va conduire à une Comportement Indéfini.
Toutefois, si vous avez une origine non const objet qui est pointé par un pointeur vers const ou référencé par une référence à const ensuite, vous pouvez utiliser const_cast à se débarrasser de la const-ness.
Jetant constness est considéré comme mauvais et doit
pasêtre évitée. Vous devriez envisager de changer le type des pointeurs que vous utilisez dans le vecteur de non-const si vous souhaitez modifier les données à travers elle.Le code ôter la const-ness de votre pointeur serait:
Mais note que c'est vraiment de la triche. Une meilleure solution serait de comprendre pourquoi vous voulez modifier un const objet, et la refonte de votre code si vous n'avez pas à.... ou supprimer la const déclaration de votre vecteur, si il s'avère que vous n'avez pas vraiment envie ces éléments pour être en lecture seule après tout.
Une autre solution est d'appeler ladite fonction dans l'entre-deux à faire des modifications sur les variables const fonction utilise. Cette idée a été ce qui a résolu mon problème étant que je n'étais pas enclin à modifier la signature de la fonction à utiliser le "changeASettingAndCallAFunction" la méthode en tant que médiateur:
Lorsque vous appelez la fonction, vous pouvez d'abord faire des modifications à la mise en avant de l'appeler, ou (si vous n'êtes pas enclin à jouer avec l'invocation de place) peut-être appeler la fonction où vous avez besoin de la modification de la variable à être propagées (comme dans mon cas).
Maintenant, quand une référence à la "someFunctionThatUsesTheSetting" est invoqué, il invoquera avec le changement de someSetting.