0
votes

C ++: Comment puis-je utiliser une implémentation différente de méthodes avec la même classe de données?

arrière-plan: Divers modules du programme, je suis impliqué dans la même combinaison d'objets regroupés dans une structure d'agrégation. Il existe des invariants bien connus imposés à cette combinaison d'objets et ces invariants sont respectés par tous les modules dans la mesure du possible. Chaque module est développé par une équipe dédiée et chaque équipe a besoin de leurs méthodes personnalisées spécifiques à un domaine pour traiter cette combinaison d'objets.

exemple: Pour vous donner une idée tangible, imaginez une classe de conteneurs de séquence. Le noyau du conteneur est identique à tous les utilisateurs: il consiste en des membres de données pour le stockage, la taille / la capacité et l'allocator. Mais l'ensemble des méthodes, le contrat et le corps de ces méthodes peuvent varier beaucoup. Un module peut implémenter des opérations de style STD, un autre module peut mettre en œuvre toutes les opérations comme méthodes de nethow, mais un autre module peut insister sur l'utilisation de leurs itérateurs vérifiés privés; Certains module critique de la performance subissent une douleur pour interdire toutes les opérations de copie, tout en restant un autre module pour faire des copies ... Ces exigences sont bien justifiées dans chaque domaine particulier de tout module donné.

spéculations: Ainsi, fournir un ensemble unique de méthodes non redondantes qui satisferaient les besoins de toutes les équipes clientes est impossible - les exigences de certaines équipes sont mutuellement exclusives. Fournir uniquement ces méthodes couramment requises par tous les modules est plutôt inutile, car la seule partie commune est probablement, probablement, le destructeur. Lancer toutes les implémentations possibles de toutes les méthodes n'est pas bonne non plus: mauvaise maintenabilité et stabilité, interface gonflée de manière confortable, beaucoup d'affrontements de nom, beaucoup de dépendances du module croisé.

la question: Quelles options dois-je laisser utiliser plusieurs implémentations indépendantes opérer sur le même ensemble de membres de données?

choses que j'ai essayées: Des solutions que je peux voir jusqu'à présent ne sont pas exactement bien gentilles et je ne suis pas entièrement content d'aucun d'entre eux. Je vais les énumérer dans des réponses, trois approches un par un.


1 commentaires

Il semble que vous ayez besoin de disposer de classes de base qui encapsulent des données, ce qui garantit certaines restrictions et certaines fonctions libres qui fonctionnent avec ces objets. Si similaire à la STD le fait avec des conteneurs ( std :: array , std :: vecteur , std :: list , ...) et algorithmes. Mais il n'est pas vraiment possible de vous dire comment cela devrait être fait dans votre cas particulier, car les détails / problèmes / question nécessaires à votre code ne sont pas connus.


3 Réponses :


0
votes

Une solution éventuelle moins que parfaite à ma propre question:

1. Ne vous embêtez pas avec des méthodes et avoir des fonctions autonomes à la place. xxx

- Ce que je n'aime pas à propos de cette approche est hostile Syntaxe, non Raii et tous les membres de données sont publics. C'est c, pas c ++.

+ du bon côté, cette approche offre des possibilités de personnalisation illimitées. Aucune restriction sur le choix de la bonne fonction de la tâche. Pas de surcharge de mémoire, pas de surcharge d'exécution (c'est-à-dire techniquement, le compilateur a les mêmes opportunités d'inlinisation et d'optimisation que ces fonctions libres soient des méthodes).


3 commentaires

Il n'est pas nécessaire que les données soient Public . Soit fournir un Setter et getter qui peut être utilisé par les fonctions non membres, ou déclarer les fonctions comme ami s


@Peter Merci pour la suggestion! Liste des ami S serait facilement atteint 200 lignes, qui n'est pas impraticable et homicale. Getter Setter individuel ANS pour chaque membre ne ferait que dissimuler le fait. Même si des problèmes d'accès étaient résolus, la syntaxe laide reste toujours.


Tous les types de données dans la bibliothèque STD n'ont qu'une quantité minimale d'une fonction membre, uniquement celles qui sont nécessaires à la mise en œuvre de la mise en œuvre des données et à fournir une interface publique. Toutes les autres sont des fonctions libres. Et si cela est fait correctement, ceci est C ++ et non c. Vous voudrez peut-être jeter un coup d'oeil à un look a the CPPCON 2017: Klaus Iglberger "GRATUITES vos fonctions!" parler.



0
votes

Une solution éventuelle moins que parfaite à ma propre question:

2. Avoir un ensemble de classes qui fonctionnent sur une instance externe de données de base par référence. xxx

- Ce que je n'aime pas À propos de cette approche, c'est qu'il impose une légère pessimisation en termes d'utilisation de la mémoire et de performance. De plus, la syntaxe rend les objets de type Teama et Teamb ressemblent à des valeurs, tandis qu'elles ont en réalité une référence sémantique.

+ bonne nouvelle est que cette approche permet une meilleure meilleure syntaxe C ++ pour les appels. (Mais toujours, il y a ce videux getcore ()) et rencontre Raii.


0 commentaires

0
votes

Une solution éventuelle moins que parfaite à ma propre question:

3. Jette le code sur la miséricorde du comportement défini de reinterpret_cast. xxx

- Cependant, de telles astuces sont interdites par le la norme. Je dois donc refuser cette approche aussi.

+ S'il était légal, il aurait offert la meilleure syntaxe des trois, la syntaxe montrant clairement la référence sémantique, avec Raii et pas de pessimisation.

ps L'invalidité de cette approche me met en panne. L'ensemble de la compatibilité de la mise en page semble donner la possibilité de communiquer des données entre processus compatibles ABI ou composants partagés. Dommage que cela ne permet pas de communiquer les données entre les parties de la même application ...


0 commentaires