Question

Parfois, je dois exposer quelques-uns des membres de la classe. Par exemple, dans le class Mechanic exemple suivant peuvent avoir besoin d'un accès direct à la composante Engine. Je l'ai lu plusieurs fois que tous les champs doivent être accessibles par des méthodes mutator (accesseurs) à cause de plusieurs raisons. Mais est-il un avantage lors de la fourniture référence non const getter:

class Car
{
    public:
        Engine & engine()
        {
           return m_engine;
        }

        //as a consequence you will also need to provide const version
        const Engine & engine() const
        {
           return m_engine;
        }

    private:
       Engine m_engine;
}

moteur sur tout simplement faire partie du public:

class Car
{
    public:
        Engine engine;
}

Vous pouvez également remplacer public avec protected si vous ne le faites pas comme cet exemple. Dans la vraie vie, vous avez quelque chose simillar en Java en matière de System.in ou System.out. On dirait que, pour être pleinement conforme à ce que certaines personnes disent, vous devez effectuer des appels comme System.getInstance().getOut().println("hello world"). Je ne vois aucun avantage sauf beaucoup de code bureaucratique dans de tels cas.

Était-ce utile?

La solution 5

J'ai trouvé le point raisonnable de fournir ces getter. Il facilite l'intégration de votre logiciel plus facile (par exemple, lorsque vous voulez traduire l'interface dans une autre langue et se lient ABIs).

Autres conseils

Ils peuvent être utiles lorsque la valeur que vous retournerez est en fait sur le tas.

template<class T> class Singleton
{
private:
    static T* m_pSingleton;

public:
    T& getSingleton() { assert(m_pSingleton); return(*m_pSingleton); };

}; // eo class Singleton

accesseurs explicites peut être trop bureaucratique; cela dépend de votre situation.

La principale raison invoquée pour avoir getter et fonctions setter est qu'il isole les clients de votre classe de changements potentiels dans la mise en œuvre à l'avenir (par exemple, ce qui se passerait si vous décidez de générer un objet Engine sur demande (plutôt que d'utiliser une variable membre), ou décider de le cacher derrière un pointeur intelligent, ou un autre récipient).

Si votre classe si elle est très simple (par exemple près d'être un POD ) et peu susceptible de changer , alors il ne peut pas être la peine faff d'avoir à mettre en œuvre les accesseurs.

Cependant, pour répondre à votre question, non const getter n'a probablement pas beaucoup de sens. Votre prototype getter doit être Engine & engine() const; sinon vous ne pourrez pas l'appeler sur des objets const de Car.

Un avantage de fournir un getter est que quand et si vous décidez de changer la façon dont les travaux de getter, le code qui utilise ce besoin de classe ne recompiler. Mais si vous avez un champ public et plus tard décidez de faire un getter, doit être recompilé tout le code. Autre que je ne vois aucune raison pratique sérieuse pour rendre votre variable privée. A noter cependant que tout cela est vrai si et seulement si vous devez fournir aux utilisateurs un moyen externe pour obtenir une référence au moteur. S'il est possible de concevoir le logiciel pour que ce besoin d'être éliminé du tout, ce serait mieux.

Je me trouvais à vous instruire sur récemment, accesseurs odeur de mauvaise conception. Mais, si vous le voulez de cette façon, en fournissant des fonctions pour obtenir et définir m_engine (Défini par vous) plutôt que de l'exposer (Vous avez pas d'intervention) signifie que vous avez un plug-point pour les changements futurs.

Pour moi, il fait ici sens:

image(i,j) = 234;

Au lieu de penser à exposer les membres privés d'une classe pense plus le long des lignes d'appeler des méthodes sur ces classes. J'ai lu un article intéressant Java, Pourquoi getter et setter Les méthodes sont mal , qui applique tout autant à C ++ comme à Java.

oui, il est logique - pour la maintenabilité, la validation et la cohérence

.

vous devrez peut-être modifier de nombreux aspects de la classe à l'avenir, en fournissant un accesseur peut aider à réduire la rupture du code client.

vous pouvez entrer dans toute la logique de validation dont vous avez besoin ici, pour faire en sorte que le moteur est un pointeur valide, n'est pas dans un état inutilisable, etc.

enfin, votre code sera compatible: vous ne devrez pas ouvrir l'en-tête de connaître la visibilité membre - vous savez toujours. Il est aussi utile avec des modèles.

Dans ce cas, vous préférez avoir besoin d'une fonction Car.fix(const Mechanic&) qui donne alors le moteur à la Mechanic, dites:. Engine.fix(const Mechanic&), comme je suppose que l'état du Engine sera modifié

L'idée originale d'utiliser des classes était de lier les données avec ses fonctions accesseurs. Si vous faites setter ou getter qui retourne simplement une donnée interne, cela signifie que vos données ne sont pas liées avec sa fonctionnalité accesseur: votre classe n'est pas complète.

Vous voulez que présentent de nouvelles données de classe une émette . Dites Car.get_exhaust() et le Car n'a pas l'échappement, seulement, quand vous le demandez produit. ;)

Ou Fire Riefle.fire() alors qu'aucun accès Riefle::Trigger sera fixé par le mécanicien comme ceci: Trigger.fix_by(Mechanic) puis le fix_by appellera par exemple Mechanic.add_working_hour(0.5). XD

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top