11
votes

C ++: L'héritage conditionnel est possible

Je travaille sur un projet de micro-processeur (Arduino). Ma bibliothèque FOO est héritée d'une bibliothèque existante de base . Plus tard, j'ai étendu les fonctionnalités de de base , dans une autre classe avancée . Cependant, avancé s'étend sur le matériel plus difficile, faisant l'une des démos déjà fabriquées inutilisables.

Ce que je pense, c'est comme suit: xxx

et mettre #define use_basic dans mon code de démonstration: < PRE> XXX

Cependant, FOO n'hérite pas de base. Est-ce que je le fais mal ici? Ou s'il y a des alternatives pour résoudre ce problème?


3 commentaires

Vous devrez définir user_basic dans chaque unité de traduction (.CPP + Inclus d'en-têtes) qui inclut foo.h , avant le #include directive. Considérez soit à l'aide d'un commutateur compilateur (qui déclare use_basic automatiquement dans chaque unité de traduction) ou mettez le #define dans l'en-tête.


@NAMED je ne suis pas d'accord. Les en-têtes ne sont rien de spécial, l'OP montre l'exemple définissant user_basic avant y compris l'en-tête. Le compilateur est exécuté sur le CPP, donc le préprocesseur voit la définition d'abord alors inclut l'en-tête (dans l'exemple de l'OP).


Je ne peux pas comprendre le -1.


4 Réponses :


1
votes

Une autre solution serait d'éviter l'héritage et d'utiliser des motifs tels que stratégie offrant beaucoup plus de flexibilité. Donc, vous pouvez modifier le comportement de FOO pendant l'exécution de de base à avancé .


1 commentaires

Cela pourrait ne pas être possible si la mémoire est limitée ou que les indirections touchent trop la performance.



2
votes

Il s'agit d'un problème de configuration de base que les vendeurs de bibliothèque sont constamment. Pour de petits projets, juste #define user_basic , le cas échéant, dans le foo.h en-tête. Pour des projets plus importants avec de nombreuses options de configuration, vous souhaiterez peut-être accéder à un fichier de configuration qui obtient #include D dans chaque en-tête de bibliothèque et définissez les choses appropriées là-bas. Dans ce cas, je ferais tout la sélection dans l'en-tête de configuration: xxx


2 commentaires

Je suis sûr que vous vouliez dire Typedef Basic Foobase; pas Typef Foobase Basic; Identique avec l'autre Typedef.


@Nawaz - Yup, merci. Je ne sais pas comment j'ai fait quelque chose qui stupide. Fixé.



1
votes

Certaines personnes ont suggéré la stratégie de motif. Si votre choix est pendant la compilation, vous devez mieux utiliser la conception basée sur les politiques: http://en.wikipedia.org/wiki/policy-based_design

Ceci est à peu près le même design que le vôtre, mais vous utilisez des modèles: xxx

à l'aide: xxx


0 commentaires

23
votes

Une solution beaucoup plus propre utiliserait des modèles: laissez le compilateur choisir la classe de base en fonction d'un argument de modèle.

Voici un exemple: P>

 Foo<Advanced>  fooWithAdvanced;
 Foo<Basic>     fooWithBasic;
 Foo<OtherBase> fooWithOtherBase;


5 commentaires

Merci! Il est tout à fait bon de savoir sur ces méthodes, ce qui ne peut pas s'adapter à mon cas, je ne sais pas si l'ajout de modèles dans des microprocesseurs le fera plus bien ou plus mauvais ...


@Xunyang: Quels "microprocesseurs" parlez-vous? Avez-vous voulu dire le pré-processeur? Si oui, vous n'avez pas besoin d'utiliser le préprocesseur avec des modèles.


Non, c'est sur Arduino, c'est donc une sorte de système intégré


@Xunyang: Je ne pense pas que le modèle entraînerait un problème d'Arduino, car une fois qu'un modèle de classe est instancié, cela devient comme n'importe quelle autre classe ordinaire.


Les modèles ne sont pas une fonction de langue par défaut pour le compilateur Arduino, vous devez donc apporter une autre bibliothèque de 3ème partie pour utiliser des modèles, ce qui prendra plus d'espace de stockage déjà à ses limites ... peut valoir la peine d'essayer, car le prochain projet :)