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:
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;
}; |
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.
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 :
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;
}; |
La nouvelle classe:
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
}; |
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.
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