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.

6voto

Eyal Shilony Points 98

Vous le savez probablement, mais je ferais simplement ce qui suit :

class Person {
public:
    std::string name() {
        return _name;
    }
    void name(std::string value) {
        _name = value;
    }
private:
    std::string _name;
};

Cette approche est simple, ne fait appel à aucune astuce et permet de faire le travail !

Le problème est que certaines personnes n'aiment pas préfixer leurs champs privés par un trait de soulignement et ne peuvent donc pas vraiment utiliser cette approche, mais heureusement pour ceux qui le font, c'est très simple :)

Les préfixes get et set n'apportent pas de clarté à vos API, mais les rendent plus verbeuses et la raison pour laquelle je ne pense pas qu'ils apportent des informations utiles est que lorsqu'une personne a besoin d'utiliser une API, si celle-ci a un sens, elle se rendra probablement compte de ce qu'elle fait sans les préfixes.

Une dernière chose, il est facile de comprendre qu'il s'agit de 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é que name() est un accesseur et name(value) est un mutateur, elle n'aura qu'à le consulter une fois dans la documentation pour comprendre le modèle.

Même si j'aime beaucoup le C#, je ne pense pas que le C++ ait besoin de propriétés du tout !

5voto

Jan Turoň Points 6598

Ce n'est pas exactement une propriété, mais elle fait ce que vous voulez de manière simple :

class Foo {
  int x;
public:
  const int& X;
  Foo() : X(x) {
    ...
  }
};

Ici, le grand X se comporte comme public int X { get; private set; } en syntaxe C#. Si vous voulez des propriétés complètes, j'ai fait un premier essai pour les implémenter. aquí .

3voto

Daniel Mor Points 72

Nope Mais vous devriez considérer que si c'est juste une fonction get : set et qu'aucune tâche supplémentaire n'est exécutée dans les méthodes get : set, rendez-la publique.

2voto

lama12345 Points 169

J'ai rassemblé les idées de plusieurs sources C++ et les ai rassemblées dans un bel exemple, encore assez simple, de getters/setters en C++ :

class Canvas { public:
    void resize() {
        cout << "resize to " << width << " " << height << endl;
    }

    Canvas(int w, int h) : width(*this), height(*this) {
        cout << "new canvas " << w << " " << h << endl;
        width.value = w;
        height.value = h;
    }

    class Width { public:
        Canvas& canvas;
        int value;
        Width(Canvas& canvas): canvas(canvas) {}
        int & operator = (const int &i) {
            value = i;
            canvas.resize();
            return value;
        }
        operator int () const {
            return value;
        }
    } width;

    class Height { public:
        Canvas& canvas;
        int value;
        Height(Canvas& canvas): canvas(canvas) {}
        int & operator = (const int &i) {
            value = i;
            canvas.resize();
            return value;
        }
        operator int () const {
            return value;
        }
    } height;
};

int main() {
    Canvas canvas(256, 256);
    canvas.width = 128;
    canvas.height = 64;
}

Sortie :

new canvas 256 256
resize to 128 256
resize to 128 64

Vous pouvez le tester en ligne ici : http://codepad.org/zosxqjTX

1voto

user692178 Points 114

Il existe un ensemble de macros écrites Aquí . Il dispose de déclarations de propriétés très pratiques pour les types de valeurs, les types de références, les types en lecture seule, les types forts et faibles.

class MyClass {

 // Use assign for value types.
 NTPropertyAssign(int, StudentId)

 public:
 ...

}

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