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