6
votes

Un pointeur peut-il alimenter une classe vides de const ou une classe de non-const?

Vraisemblablement pas. Voici mon cas d'utilisation:

J'ai deux classes A & B. P>

A(): b_(&null_b) {};


11 commentaires

Je ne devrais probablement pas suggérer ceci mais ... const_cast?


Cherchez-vous un poids volé? Mais gardez à l'esprit que tous les indicateurs seraient logiquement


@Borglaireur Comment cela aiderait-t-il ici? Vous ne pouvez pas au moment de l'exécution de décider de const_cast le pointeur d'être const (s'il pointe de votre objet Nil)


Oui, il peut, iff c'est un pointeur à const .


Vous ne pouvez pas vraiment vous échapper du fait que le désarférance d'un pointeur non constitutionnel peut modifier la cible. Cela peut arriver alors que voulez-vous arriver? Abandonner ou quelque chose?


@Neilkirk Je veux être capable d'être capable de désirer le pointeur de non-Const quand je ne pointe pas un "objet null" car je souhaite modifier l'objet déréférencé. C'est l'objet "NULL" qui ne doit jamais changer.


Mais vous n'avez aucun moyen d'empêcher le pointeur d'être défiguré lorsque vous dirigez l'objet vide. Si vous savez quand il pointe de l'objet vide pour ne pas le faire, vous allez simplement utiliser une chaîne vide directement.


@ Macbeth'Senigma de sorte que fondamentalement, si vous Dréérence, le PTR et c'est l'objet NULL, rien ne devrait être appelé?


@BolGlairer Si un PTR déséroférencé pointe sur l'objet NULL, je souhaite accéder aux variables vides de l'objet (directement ou via des accesseurs). Cela évite de devoir vérifier pour le nullptr chaque fois que j'ai besoin de dréréférence fréquente, y compris des surcharges de l'opérateur.


@ Macbeth'Senigma Ce que je veux savoir, vous avez-vous dit que l'objet NULL ne devrait pas changer. Que devriez-vous arriver si quelqu'un tente d'appeler une méthode sur un objet nul qui le modifierait? Devrait-il ne pas compiler?


@Borglaireur Eh bien, oui - Je cherche la protection de la const (Compiler l'échec) si le programme tente de modifier l'objet NULL. Ce ne serait pas un objet nul s'il est modifié. Être vaguement semblable à la modification de nullptr. Je cherche au moins un moyen de garantir qu'il ne peut pas être modifié.


3 Réponses :


1
votes

Eh bien, peut-être que c'est totalement hors du point, mais ... pourriez-vous utiliser une instance de B au lieu de pointeur sur B à l'intérieur d'un? Cela résoudrait la proportion potentielle NullPtr.

EDIT Eh bien, si B est trop grand, vous pouvez créer une enveloppe légère autour d'elle et stocker une instance de ce wrapper à l'intérieur de A. L'emballage vous fournirait quelque chose de significatif si B est NullPtr.


2 commentaires

Non - je dois indiquer cette structure plutôt complexe dans le projet réel. Non seulement je ne voudrais pas que les frais généraux de la copie, je dois le mettre à jour et non une copie.


Merci pour ton aide! Je pense que dans l'essence Mark and Bill's Solution était une courte et douce enveloppe autour de l'objet NULL que vous suggérez.



3
votes

Vous ne pouvez pas avoir de point de pointeur "non-const" sur un objet const . Et malheureusement, à l'aide de const_cast pour supprimer le const de l'objet signifie que certains code peuvent essayer de modifier l'objet. (Notez que le comportement indéfini de jeter const sauf si l'objet d'origine n'est pas constitué, donc techniquement, le compilateur est autorisé à générer du code qui se bloque si cela se produit. Malheureusement, de nombreux cas, il a gagné ' T crash lorsque l'objet est quelque chose de plus complexe que const char * ou const int [] - permettant au code de continuer après avoir écrasé votre objet que vous ne vouliez pas être écrit).

Cependant, puisque la classe B a un membre b_string _ membre privé, aucun objet extérieur n'a pu le toucher, de sorte que vous pouvez vous assurer que toute utilisation de b_string_ est effectué via une fonction virtuelle (ou plusieurs fonctions virtuelles), puis dérivez une autre classe à partir de B où le (s) virtuel (s) dit "Désolé, tu ne peux pas faire ça "Lorsque le code tente de modifier b_string dans l'objet dérivé.


6 commentaires

Le const_cast est UB en premier lieu, sauf si vous savez que le pointe est réellement mutable


Oui, mon point de vue était que si vous lancez la Constance, cela n'arrête pas de la modification de la modification de la modification - il s'agit d'UB est un peu à côté du point à ce stade, depuis la raison de la fabrication const est vraisemblablement que vous ne le voulez pas modifié - et donné la moyenne dans la plupart des systèmes, il ne se placera probablement pas, il sera donc heureux de travailler avec plaisir avec l'objet accessible et des choses étranges.


La modification de cela pourrait très bien planter l'application. En fait, c'est précisément ce qui se passe lorsque vous Ecrivez via un const char * dans la moyenne Hello-World Niveau App . Je suppose que mon point est "UB n'est jamais à côté du point"


Et vous connaissez une combinaison OS / compilateur où elle fait? Je ne dis pas que cela ne peut pas arriver, juste que je ne suis pas au courant d'une telle combinaison.


Ce n'est pas la même chose qu'un const b objet, tho '. Un Const Char * est définitivement stocké en lecture seule en lecture seule et va en effet planter. C'est en fait pire quand il ne plait pas - parce que cela traitait avec bonheur après avoir modifié l'objet que vous avez pensé était const et ne pouvait pas être modifié. Mais si cela vous rend plus heureux, je modifierai dans un «comportement indéfini».


Merci pour les commentaires. Tu m'as commencé à penser sur le bon chemin. J'ai donné la coche à la marque et à la facture parce qu'elles m'ont fait un peu plus concrète pour moi. J'espère que c'est bon.



5
votes

Au lieu de contenir un pointeur sur un objet B , créez une classe de base avec des méthodes virtuelles et stockez des pointeurs à ce sujet. Dérivez à la fois votre classe B Classe et un Classe NULL_B de celui-ci, mais ne laissez pas les méthodes sur null_b faire des modifications. Maintenant, même si votre null_b n'était pas const , cela n'a plus d'importance.

En tant que couche supplémentaire de protection, vous pouvez apporter une tentative de modification de l'objet null_b lancer une exception afin que vous puissiez détecter et trouver votre erreur logique.


2 commentaires

Un exemple de travail (sauf que null_b Derribe directement de b) ici: ideone.com/m5ezfh


@bill et Markransom - Merci ça va travailler. Merci pour la facture de code! Cela a fait cela immédiatement évident. :)