105 votes

C++11 a-t-il des propriétés de type C# ?

En C#, il existe une belle 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; }

Existe-t-il un concept de ce type dans le C++11 qui me permette de bénéficier d'une certaine souplesse syntaxique à cet égard ?

73 votes

Cela pourrait être fait avec quelques macros. s'enfuit honteusement

0 votes

Je rends tout public et j'accède directement aux champs dans le cadre de l'interface publique de la classe. Si un champ doit vraiment être privé, je le fais précéder d'un trait de soulignement, mais on peut quand même y accéder s'il y a une raison impérative. C'est une mauvaise idée si vous avez des développeurs incompétents dans votre équipe qui en abusent. canards

7 votes

@Eloff : Rendre tout public est TOUJOURS une mauvaise idée.

18voto

thesaint Points 513

Jetez un coup d'œil à la classe de propriété que j'ai assemblée au cours des dernières heures : https://codereview.stackexchange.com/questions/7786/c11-feedback-on-my-approach-to-c-like-class-properties

Il vous permet d'avoir des propriétés qui se comportent comme ceci :

CTestClass myClass = CTestClass();

myClass.AspectRatio = 1.4;
myClass.Left = 20;
myClass.Right = 80;
myClass.AspectRatio = myClass.AspectRatio * (myClass.Right - myClass.Left);

17voto

Marco Dinacci Points 837

Comme beaucoup d'autres l'ont déjà dit, il n'y a pas de support intégré dans la langue. Toutefois, si vous utilisez le compilateur Microsoft C++, vous pouvez tirer parti de l'extension spécifique à Microsoft pour les propriétés, qui est documentée. ici.

Voici l'exemple de la page liée :

// declspec_property.cpp
struct S {
   int i;
   void putprop(int j) { 
      i = j;
   }

   int getprop() {
      return i;
   }

   __declspec(property(get = getprop, put = putprop)) int the_prop;
};

int main() {
   S s;
   s.the_prop = 5;
   return s.the_prop;
}

14voto

David Peterson Points 245

Non, le C++ n'a pas de concept de propriétés. Bien qu'il puisse être gênant de définir et d'appeler getThis() ou setThat(value), vous indiquez au consommateur de ces méthodes qu'une certaine fonctionnalité peut 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 rendent 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.

Pour l'anecdote, je travaillais sur une application .NET (un CMS très connu) en essayant de créer un système d'adhésion des clients. En raison de la façon dont ils avaient utilisé les propriétés pour leurs objets utilisateurs, des actions se déclenchaient que je n'avais pas prévues, ce qui faisait que mes implémentations s'exécutaient de façon bizarre, y compris par récursion infinie. Ceci était dû au fait que leurs objets utilisateurs faisaient des appels à la couche d'accès aux données ou à un système de cache global lorsqu'ils tentaient d'accéder à des choses simples comme StreetAddress. Leur système entier était fondé sur ce que j'appellerais un abus de propriétés. S'ils avaient utilisé des méthodes au lieu de propriétés, je pense que j'aurais compris beaucoup plus rapidement ce qui n'allait pas. S'ils avaient utilisé des champs (ou au moins fait en sorte que leurs propriétés se comportent davantage 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 je me suis un peu emporté. Ce nettoyage devrait être plus professionnel.

13voto

Kerrek SB Points 194696

Non, ça ne l'est pas.

Cela dit, la philosophie du C++ est de promouvoir encapsulation . Si vous trouvez que votre interface ne fait que passer des éléments membres ("getters et setters"), réfléchissez-y à deux fois. Votre classe doit avoir une interface significative pour ce que fait la classe plutôt que de servir de récipient pour les affaires. Les objets membres doivent être un détail d'implémentation plutôt que de faire partie de l'interface publique. Si vous voulez un conteneur libre, il suffit d'utiliser un objet de type std::tuple ou quelque chose comme ça.

13voto

Kaiserludi Points 720

Sur la base de https://stackoverflow.com/a/23109533/404734 voici une version avec un getter public et un setter privé :

struct Foo
{
    class
    {
            int value;
            int& operator= (const int& i) { return value = i; }
            friend struct Foo;
        public:
            operator int() const { return value; }
    } alpha;
};

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X