En C #, il existe un bon sucre de syntaxe pour les champs avec getter et setter. De plus, j'aime les propriétés auto-implémentées qui me permettent d'écrire
public Foo foo { get; private set; }
En C ++, je dois écrire
private:
Foo foo;
public:
Foo getFoo() { return foo; }
Y a-t-il un tel concept dans le C ++ 11 qui me permet d'avoir du sucre de syntaxe à ce sujet?
Réponses:
En C ++, vous pouvez écrire vos propres fonctionnalités. Voici un exemple d'implémentation de propriétés utilisant des classes sans nom. Article Wikipédia
Vous pouvez écrire vos propres getters et setters en place et si vous voulez un accès aux membres de la classe de détenteurs, vous pouvez étendre cet exemple de code.
la source
_alpha
pour la variable privée etalpha
pour la référence.sizeof(Foo)
.C ++ n'a pas cela intégré, vous pouvez définir un modèle pour imiter la fonctionnalité des propriétés:
Pour définir une propriété :
Pour implémenter un getter / setter personnalisé, héritez simplement:
Pour définir une propriété en lecture seule :
Et pour l' utiliser en classe
Owner
:Vous pouvez définir certains des éléments ci-dessus dans des macros pour les rendre plus concis.
la source
virtual
n'est probablement pas nécessaire pour la plupart des cas d'utilisation, car il est peu probable qu'une propriété soit utilisée de manière polymorphe.Il n'y a rien dans le langage C ++ qui fonctionnera sur toutes les plates-formes et tous les compilateurs.
Mais si vous êtes prêt à rompre la compatibilité multiplateforme et à vous engager dans un compilateur spécifique, vous pourrez peut-être utiliser une telle syntaxe, par exemple dans Microsoft Visual C ++, vous pouvez le faire
la source
Vous pouvez émuler getter et setter dans une certaine mesure en ayant un membre de type dédié et en remplaçant
operator(type)
etoperator=
pour lui. Que ce soit une bonne idée est une autre question et je vais à+1
la réponse de Kerrek SB pour exprimer mon opinion là-dessus :)la source
friend
au propriétaire du champ.Jetez peut-être un œil à la classe de propriété que j'ai assemblée au cours des dernières heures: /codereview/7786/c11-feedback-on-my-approach-to-c-like-class-properties
Cela vous permet d'avoir des propriétés qui se comportent comme ceci:
la source
Avec C ++ 11, vous pouvez définir un modèle de classe Property et l'utiliser comme ceci:
Et voici le modèle de classe Property.
la source
C::*
dire? Je n'ai jamais rien vu de tel auparavant?C
. Ceci est similaire à un pointeur de fonction simple, mais pour appeler la fonction membre, vous devez fournir un objet sur lequel la fonction est appelée. Ceci est réalisé avec la ligneitsObject->*itsSetter(theValue)
dans l'exemple ci-dessus. Voir ici pour une description plus détaillée de cette fonctionnalité.Comme beaucoup d'autres l'ont déjà dit, il n'y a pas de support intégré dans la langue. Toutefois, si vous ciblez le compilateur Microsoft C ++, vous pouvez profiter de l'extension spécifique à Microsoft pour les propriétés qui est documentée ici.
Voici l'exemple de la page liée:
la source
Non, C ++ n'a pas de concept de propriétés. Bien qu'il puisse être difficile de définir et d'appeler getThis () ou setThat (valeur), vous faites une déclaration au consommateur de ces méthodes que certaines fonctionnalités peuvent se produire. L'accès aux champs en C ++, en revanche, indique au consommateur qu'aucune fonctionnalité supplémentaire ou inattendue ne se produira. Les propriétés rendraient cela moins évident car l'accès aux propriétés semble à première vue réagir comme un champ, mais réagit en fait comme une méthode.
En passant, je travaillais dans une application .NET (un CMS très connu) essayant de créer un système d'adhésion client. En raison de la manière dont ils utilisaient les propriétés de leurs objets utilisateur, des actions se déclenchaient que je n'avais pas anticipées, provoquant l'exécution de mes implémentations de manière bizarre, y compris une récursivité infinie. Cela était dû au fait que leurs objets utilisateur appelaient la couche d'accès aux données ou un système de mise en cache global lorsqu'ils tentaient d'accéder à des choses simples comme StreetAddress. Tout leur système était fondé sur ce que j'appellerais un abus de propriété. S'ils avaient utilisé des méthodes plutôt que des propriétés, je pense que j'aurais compris ce qui n'allait pas beaucoup plus rapidement. S'ils avaient utilisé des champs (ou du moins fait en sorte que leurs propriétés se comportent plus comme des champs), je pense que le système aurait été plus facile à étendre et à maintenir.
[Edit] J'ai changé d'avis. J'avais eu une mauvaise journée et j'ai fait un peu de diatribe. Ce nettoyage devrait être plus professionnel.
la source
Basé sur https://stackoverflow.com/a/23109533/404734, voici une version avec un getter public et un setter privé:
la source
Ce n'est pas exactement une propriété, mais il fait ce que vous voulez de manière simple:
Ici, le grand X se comporte comme
public int X { get; private set; }
dans la syntaxe C #. Si vous voulez des propriétés à part entière, j'ai fait un premier plan pour les implémenter ici .la source
X
du nouvel objet pointera toujours vers le membre de l'ancien objet, car il est simplement copié comme un membre pointeur. C'est mauvais en soi, mais lorsque l'ancien objet est supprimé, vous obtenez une corruption de mémoire en plus. Pour que cela fonctionne, vous devez également implémenter votre propre constructeur de copie, opérateur d'affectation et constructeur de déplacement.Vous le savez probablement, mais je ferais simplement ce qui suit:
Cette approche est simple, n'utilise aucune astuce intelligente et elle fait le travail!
Le problème est cependant que certaines personnes n'aiment pas préfixer leurs champs privés avec un trait de soulignement et ne peuvent donc pas vraiment utiliser cette approche, mais heureusement pour ceux qui le font, c'est vraiment simple. :)
Les préfixes get and set n'ajoutent pas de clarté à votre API mais les rendent plus verbeux et la raison pour laquelle je ne pense pas qu'ils ajoutent des informations utiles est que lorsque quelqu'un a besoin d'utiliser une API si l'API a du sens, elle réalisera probablement de quoi il s'agit se passe des préfixes.
Encore une chose, il est facile de comprendre que ce sont des propriétés car
name
n'est pas un verbe.Dans le pire des cas, si les API sont cohérentes et que la personne n'a pas réalisé qu'il
name()
s'agit d'un accesseur etname(value)
est un mutateur, elle n'aura qu'à la rechercher une fois dans la documentation pour comprendre le modèle.Autant j'aime C #, je ne pense pas que C ++ ait besoin de propriétés du tout!
la source
foo(bar)
(au lieu du plus lentfoo = bar
), mais vos accesseurs n'ont rien à voir avec les propriétés du tout ...foo(bar)
au lieu de cela,foo=bar
ce qui peut être obtenu avec unevoid foo(Bar bar)
méthode mutator sur une_foo
variable membre.Non .. Mais vous devriez considérer si c'est juste la fonction get: set et aucune tâche supplémentaire préformée dans les méthodes get: set ne la rendent publique.
la source
J'ai rassemblé les idées de plusieurs sources C ++ et les ai mises dans un bel exemple encore assez simple pour les getters / setters en C ++:
Production:
Vous pouvez le tester en ligne ici: http://codepad.org/zosxqjTX
la source
Votre classe a-t-elle vraiment besoin d'appliquer un invariant ou s'agit-il simplement d'un groupement logique d'éléments membres? Si c'est ce dernier, vous devriez envisager de faire de l'objet une structure et d'accéder directement aux membres.
la source
Il existe un ensemble de macros écrites ici . Cela a des déclarations de propriétés pratiques pour les types valeur, les types référence, les types en lecture seule, les types forts et faibles.
la source