2014-07-22 4 views
0

Quel est le style C++ préféré, en utilisant une fonction get et set pour obtenir et définir la valeur d'une variable membre, ou simplement rendre publique la variable membre?Utilisation d'une fonction get pour rendre une variable membre publique

class MyClass 
{ 
public:  
    std::string getValue(); 
    std::string setValue(); 
private:  
    std::string value; 
}; 

contre

class MyClass 
{ 
public: 
    std::string value; 
}; 

Le second semble plus propre et je ne vois pas vraiment un avantage au premier, autre que vous obtenir un peu plus d'argent si vous êtes payé par des lignes de code .

+4

Le premier ne permet pas de modifications. – chris

+1

L'avantage de la première approche est qu'elle n'expose pas l'implémentation (mutable) et l'état privé de l'objet. –

+0

Eh bien, je pourrais aussi inclure une fonction 'std :: string setValue();' si je veux faire des changements. J'aurais dû clarifier cela. – Lighthat

Répondre

4

Je ne vois pas vraiment un avantage au premier, autre que vous obtenir un peu plus d'argent si vous êtes payé par des lignes de code.

Par ce raisonnement, la seconde approche pourrait vous donner plus d'argent, l'affacturage dans le coût de l'entretien. Imaginez, un jour vous changeriez value pour être calculé à partir des autres membres. Avoir un getter facilite l'ajout de ce comportement sans affecter la base de code. Le fait qu'il y ait une valeur string stockée dans chaque instance devrait être un détail d'implémentation, ne faisant pas partie de l'API visible publiquement (du moins en théorie: sans héritage, le fait que le membre existe soit visible par n'importe quel utilisateur)). Il est ennuyeux d'avoir à écrire des getters et des setters à la mode, mais dans une perspective à long terme, cela vaut la peine.

Souvent, cependant, les classes qui ont trop de paires setter et getter ont d'autres défauts de conception et généralement un état mutable trop important. En outre, en C++, si une classe avec des milliers de paires getter/setter ne contient que l'état et ne définit aucun comportement, il devrait plutôt s'agir d'un struct.

+0

Mais changer l'implémentation pour calculer 'value' à la volée rendrait le setter (qui fait déjà partie de l'interface) inutile. – John

+0

C'est vrai - peut-être que le setter n'a jamais été utilisé et peut être retiré en toute sécurité. Edité cependant. –

+0

@Alex Pour être clair cependant, quand vous dites "les classes qui ont trop de paires setter et getter ont d'autres défauts de conception", vous n'impliquez pas que l'utilisation de getters et setters est un défaut de conception, n'est-ce pas? – Lighthat

4

Ce n'est pas une bonne pratique de «montrer» les entrailles de l'objet au monde. Probablement plus tard, vous pouvez vouloir changer la mise en œuvre de classe ou même faire votre valeur de ne pas être std::string. Comme le projet grandit, beaucoup de choses peuvent changer, et sûrement, vous pouvez ajouter le getValue plus tard, mais dans ce cas vous dépréciez l'ancienne "API" et en créant une nouvelle, cela peut causer des problèmes avec la mise à jour et ainsi de suite.

De plus, rendant public membre permet aux utilisateurs de lire/modifier ce membre, sans avertir la classe elle-même. Cela peut créer des problèmes de "mauvaise conception".

+0

'ou même faire de votre valeur ne pas être std :: string' - comment l'utilisation de la fonction d'accès peut aider dans ce cas? – Gluttton

+0

@Gluttton un getter peut convertir un type de type interne à un autre. – PSIAlt

1

Un membre de classe publique est contre l'encapsulation, qui est l'un des principes OO.

La convention la plus courante est de ne pas utiliser les mots get et set, seulement le nom de la variable. Nous laissons simplement le compilateur décider s'il est défini ou obtenu par la présence de l'argument ou de son absence.

La variable membre doit commencer par un préfixe 'm_'.

Autre option est de commencer le nom de la fonction avec une lettre majuscule et la variable avec un régulier ..

Cette convention utilisée par de nombreuses bibliothèques open source comme ImageMagick et plus.

Votre classe devrait être la suivante:

class MyClass 
{ 
public: 
    void value(const std::string& v){ 
     m_value=v; 
    } 
    const std::string& value()const { 
     return m_value; 
    } 
private: 
    std::string m_value; 
}; 
Questions connexes