8
votes

Méthode d'échange avec les membres de Const

Je souhaite mettre en œuvre une méthode Swap () pour ma classe (appelons-le a) pour effectuer un opérateur de copie et de swap = (). Pour autant que je sache, la méthode d'échange doit être mise en œuvre en échangeant tous les membres de la classe, par exemple: xxx

mais que dois-je faire si j'ai un membre du Cons-Cons-ce? Je ne peux pas appeler std :: échange pour cela, donc je ne peux pas coder A :: Swap ().

Edit: En fait, ma classe est un peu plus compliquée. Je veux sérialiser et désérialiser. Le membre Const est un élément de données qui ne changera pas (son identifiant par exemple) dans cet objet. Alors je pensais écrire quelque chose comme: xxx

et appelez ce code: xxx

Je suis désolé pour un tel libellé vague.


21 commentaires

Neil Butterworth: Je ne veux pas le changer logiquement, je veux échanger physiquement tous les membres de la classe. Ils ne le remarquerent pas)


Aidez-moi s'il vous plaît. Qu'est-ce que Opérateur = () faire s'il y avait un membre de const dans la classe? Je veux dire quelle est l'intention?


@ f0b0s: Si vous nous donnez la définition de votre classe, vous essayez d'écrire un échange pour, nous vous dirons comment obtenir les résultats que vous désirez. Mais une classe avec un membre de données Cons est une classe non destinée à être modifiée.


Je suis d'accord avec Gman, s'il dispose d'un membre de données Const, vous devriez plutôt copier la classe.


Cela pourrait aider si nous avons compris le contexte plus large. Qu'est-ce que vous essayez vraiment d'atteindre? Qu'est-ce que classe A , vraiment?


@John (+1) @NEIL si l'objet de la personne A (ACCT-ID Const) représente de l'adresse MEM 1 va être échangé par la personne B (ACCT-ID CONSTRY) représentée par l'adresse mémoire 2. Puis je ne vois aucun préjudice En échangeant l'objet - y compris l'ACCT-ID ... L'échange est censé ... (Attendez-vous .....) Swap! Cela ne signifie pas modifier la valeur ... C ++.


Hassan Syed: Merci, vous avez expliqué exactement mon problème.


F0B0S: Donc, classe A comme un objet de document que vous essayez de charger et de sauvegarder?


@Hassan: Dans ce cas, alors pourquoi la classe a-t-elle des membres const ?


@John DRAINBLE MM ... une personne a une couleur de la peau de la peau, par exemple, ou Const sexe.


John Dibling: Eh bien, c'est un conteneur avec STD :: Liste des données de la taille constante.


@ f0b0s: OK, assez juste. Mais vous n'allez pas échanger cette personne pour une autre. Le point de ceci est que lorsque vous avez une classe avec des variables de membre Const et une méthode d'échange, quelque chose n'est pas juste. Soit les membres ne devraient pas être constants ou vous ne devriez pas échanger. En général.


@ f0b0s, mais si vous avez l'intention de les échanger (rendre votre classe mutable), ces données ne doivent pas être constantes. Aussi, est la STD :: Liste elle-même constante?


@ f0b0s: Et pourquoi voulez-vous échanger des listes? Ne pas essayer de vous trachant ici. J'essaie juste d'arriver au fond de ce que vous essayez d'accomplir.


Votre code semble toujours manquer quelque chose. Et je ne vois toujours pas pourquoi vous voulez construire temporaire et échanger. (Au moins, êtes-vous sûr de vouloir une méthode d'échange public. Peut-être que vous voulez juste un assistant privé d'une sorte, ce qui permettrait d'échanger les choses que vous voulez échangez?)


J'ai vu votre édition, mais ce qui n'a pas de sens pour moi, c'est pourquoi le membre de la taille est constitué? Supposons que cela a du sens pour échanger des listes. Dans ce cas, le membre de taille ne devrait pas être constitué, car la taille de la liste contenue peut changer.


@Unclebens Oui, j'ai mis en œuvre SwapnonConst, mais je n'aime pas cette réalisation. @John Dibling maintenant, cette taille de const est la taille de chaque élément de la liste des non-Const.


@ f0b0s: ah, je vois. Ce n'est pas une propriété de l'élément, et pas la liste?


@ f0b0s: ou alternativement, si la taille de l'élément est vraiment immuable, car elle ne modifiera même pas d'accrocher différentes instanciations de la liste, alors ne devrait-il pas être un membre de la const statique de la liste? (Je préfère toujours l'attribut de l'élément, cependant)


@John Dibling peut vous tromper, les deux versions sont vraiment bonnes, merci!


@John Dibling Const est un qualificatif fantastique - quand il en a capturé les exigences du problème à portée de main; La résolution de problèmes est ce que nous faisons avec les langages de programmation. Parfois, le problème empêche de rédiger un code élégant et, dans ce cas, nous devons faire des concessions. Cela pourrait bien être l'un de ces cas - les valeurs sont en effet consenses - Cependant, les emplacements de mémoire peuvent parfois être dans le code, ne pas être - peut-être que l'OP devrait utiliser T * const x?. J'ai ajouté cela comme une réponse.


7 Réponses :


0
votes

C'est pourquoi const_cast a été créé. N'oubliez pas de ne pas tirer votre pied.

edit: OK, je concède - const_cast n'a pas été fait pour ce problème. Cela pourrait fonctionner avec votre compilateur, mais vous ne pouvez pas compter dessus et si les démons viennent voler de vos narines, ne me blâmez pas.


4 commentaires

Ce n'est certainement pas la raison pour laquelle const_cast a été créé. Si le membre est véritablement const en utilisant const_cast pour activer l'écriture à ce membre entraînera un comportement non défini. const_cast ne permet que d'écrire sur quelque chose qui n'est pas const mais où le code d'écriture n'a qu'un pointeur sur const ou un Const référence.


Je ne pense pas que ce soit une bonne idée. Pour autant que je sache, const_cast sur un objet véritablement constitué provoque un comportement non défini.


(+1) const_cast est utilisé lorsque la sémantique de la langue ne correspond pas à la sémantique du problème à la main ....


Hein, sorta. Mettez un autre moyen, Const_cast est utilisé lorsque quelqu'un s'envole et que vous devez pirater.



9
votes

Je pense que ce que vous voulez vraiment, c'est avoir une structure de données interne que vous pouvez facilement échanger entre les objets. Par exemple: xxx

Ceci garde la constante de valeur z dans une instance de A des données internes d'objet, mais vous pouvez échanger les données internes de deux objets A (y compris la constante z la valeur) sans violer la constance de la constance.


3 commentaires

Ouais, à l'exception du comportement du constructeur de copie de la copie est au mieux douteux et son opérateur d'affectation est plat. N'oubliez donc pas d'écrire un constructeur de copie et d'un opérateur d'affectation correct si vous allez cet itinéraire.


Eh bien, oui, vous devez toujours suivre la règle générale de "si vous en avez besoin de: destructeur, constructeur de copie, opérateur d'affectation, alors vous avez besoin des trois." (et swap est une sorte d'opérateur d'affectation). Le code ci-dessus est destiné à montrer l'idée derrière l'échange de const-correct, ne pas être une implémentation complète.


Ceci fait p_data-> z non modifiable mais vous pouvez modifier l'objet a_data . Normalement, si vous voulez qu'un membre du Cons-ce soit pour assurer que personne ne le change ...



3
votes

F0B0S, un bon principe de design est de concevoir vos objets pour être immuables . Cela signifie que l'objet ne peut pas changer une fois créé. Pour "changer" l'objet, vous devez copier l'objet et vous assurer de modifier les éléments souhaités.

Cela étant dit, dans ce cas, il faut regarder à l'aide d'un constructeur de copie pour copier les objets que vous souhaitez échanger, puis échanger les références à l'objet. Je peux comprendre que ce serait tentant de pouvoir changer les éléments d'un objet sous le capot, mais il serait préférable de faire une copie de l'objet et de remplacer les références à cet objet avec le nouveau nouveau < / fort> objet à la place. Cela vous met autour de tout excroiité.

J'espère que cela aide.


0 commentaires

1
votes

Je vous suggère d'utiliser des pointeurs vers les instances. Les pointeurs peuvent être échantillonnés beaucoup plus facilement que les données de la classe ou struct .

Le seul moyen de swap une valeur constante est de Créez un autre objet, ou clone l'objet actuel.

donné une structure: xxx

Ma compréhension est que vous voulez échanger des instances de quelque chose comme my_tructeur ci-dessus. Vous pouvez copier les membres mutables (non constitutifs) mais pas le membre const . La seule méthode pour altérer le membre const est de créer une nouvelle instance avec une nouvelle valeur pour le membre const .

Peut-être que vous devez repenser votre Conception.


0 commentaires

0
votes

IMHO Vous devez envisager de ne pas échanger les membres de Const.

PD: Je pense que vous pourriez envisager d'utiliser la réflexion dans votre approche. Donc, vous n'avez pas à maintenir la fonction.


2 commentaires

C ++ ne prend pas en charge la réflexion.


Merci Tyler, je ne l'avais pas réalisée. :)



5
votes

Après une bonne nuit de sommeil, je pense que la meilleure réponse est d'utiliser un pointeur non-const à une valeur de const - après toutes ces sémantiques que vous essayez de capturer.


1 commentaires

Merci, vous êtes le seul, qui a compris le problème: je ne veux pas changer de valeur, mais changer l'adresse (lieu) de la variable Const. J'ai fait cela avec Poitre, c'est le plus élégant que je pense.



0
votes

tl; dr; : C'est un comportement indéfini.

Référence / Raison: CPPCON 2017: Scott Schurr "Type Punning in C ++ 17: Éviter Comportement défini de Pun, @ 24m52s + - "

Mon interprétation, par exemple:

Supposons que vous créiez un objet de type t , qui ont des membres const . Vous pouvez transmettre cet objet sous forme de référence non-const à une fonction f (& t) qui le manipule, mais vous vous attendez à ce que les membres const ne soient pas actifs après l'appel . Swap peut être appelé dans les références non-Constons, et elle peut se produire dans la fonction f , rompre la prémisse des membres const à l'appelant.

Chaque partie de votre code qui utilise échange devrait affirmer que l'objet de type t étant échangé n'appartient à aucun contexte où le const < / code> Les membres sont supposés constants. Qui est impossible de vérifier automatiquement *.

* Je viens de supposer que cela est impossible de vérifier parce que cela semble être une extension de la non-détérioration du problème d'arrêt.


0 commentaires