Bonjour.
J'ai déjà posé la question sur SO (http://stackoverflow.com/q/14515224/882932) mais les réponses que j'ai obtenu ne me satisfont pas trop. Pour illustrer le problème je vais prendre un exemple.
Considérons la classe suivante:
D'un point de vue utilisateur, MyClass1 est une classe qui possède 3 propriétés x, y et z interdépendantes qui peuvent être accédées par des getter,et qui peuvent être modifiées par des setter. D'un point de vue de l'utilisateur toujours, le fait qu'en interne il y ait _x, _y mais pas _z est un détail d'implémentation : les getter et les setter permettent de garantir l'accès/la modif comme si on avait toutes les variables en interne.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 class MyClass1 { public: double x() const {return _x;} // getter double y() const {return _y;} // getter double z() const {return _x*_y;} // getter void x(const double var) {_x = var;} // setter void y(const double var) {_y = var;} // setter void z(const double var) {_x = var; _y = 1;} // setter protected: double _x; double _y; };
La question posée est la suivante: y-a-t-il une façon d'éviter d'avoir à écrire des getter et des setter qui ne font "rien de spécial" comme ceux de x et ceux de y ?
Une solution que j'ai trouvé consiste à passer par un wrapper et l'overload de l'opérateur ().
Le wrapper :
La nouvelle classe:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 template <typename Type> class Wrapper { public: constexpr Wrapper(const Type& value) {_value = value;} constexpr Type& operator()() {return _value;} constexpr const Type& operator()() const {return _value;} constexpr void operator()(const Type& value) {_value = value;} constexpr operator Type() const {return _value;} protected: _value; };
L'utilisateur peut toujours utiliser x(), y() et z(), sauf que cette fois je n'ai pas eu à écrire les getter et setter de x et y.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 class MyClass2 { public: Wrapper<double> x; Wrapper<double> y; double z() const {return x*y;} // getter void z(const double var) {x = var; y = 1;} // setter };
La question est la suivante : est-ce une pratique "acceptable" ou est-ce à éviter en terme de design (ou encore pire est-ce "dangereux" (et si c'est le cas, pourquoi)) ?
Partager