Normalement, si vous connaissez tous les types que vous avez l'intention de créer avant de la main, vous pouvez simplement faire quelque chose comme ceci: mais cela devient fastidieux, car chaque fois que vous créez une nouvelle classe , vous devez mettre à jour l'énum. En outre, la créature_types n'est toujours que des articles dans un énumé - comment se lier à une classe actuelle? P> Je me demandais s'il y avait une manière, je pouvais simplement écrire les cours et au moment de l'exécution, sans réellement Instancitation d'un objet, créez un ensemble contenant tous les types. P> est-ce possible en C ++? En Java, il y a quelque chose appelé "blocs statiques", qui sont exécutés lorsque la classe est chargée par la JVM. P> Edit: Cette question ne concerne pas les blocs statiques - c'est juste un exemple - je me demande si je me demande si Il y a quelque chose que je peux exécuter une méthode ou un bloc de code, donc je sais à quels classes existent au moment de l'exécution, sans créer un objet P> EDIT: je voulais dire ensemble de tous types, pas des "cartes", Donc, je peux créer un objet de chaque type, sans avoir à gérer une liste. P> Edit: La raison pour laquelle je le veux, c'est parce que j'essaie de créer une fonction pouvant appeler des méthodes sur toutes les classes dérivées qui font partie de l'application. Par exemple, disons que j'ai plusieurs classes qui dérivent de la classe FOO et ont une balle (): p> au moment de l'exécution, j'aimerais savoir à propos de tout le dérivé classes afin que je puisse appeler: p> EDIT: Notez que je n'ai pas besoin de savoir à propos de tous les membres de chaque classe dérivée, je veux juste savoir ce que tout le dérivé Les classes sont donc pour que je puisse appeler des balles (), sur chacun d'entre eux. P> Edit: Cette question est similaire: Comment enregistrer automatiquement une classe sur la création p> mais malheureusement, il stocke une STD :: String (). Comment se référer à la classe actuelle? P> Modifier: Dans la réponse de Smeehey ci-dessous, dans la méthode principale, comment puis-je créer une instance de chaque classe et appeler des méthodes statiques et non statiques? < / p> p>
3 Réponses :
Utilisez le CRTP conception avec interface pour "ancêtre" commun: J'ai essayé cette solution, mais je ne sais pas pourquoi le base statique const * _model; code> n'est pas créé lors de l'exécution du programme. P> P>
Qui sont plusieurs classes de base.
CRTP semble être sur la bonne voie. Mais comment vais-je stocker une collection de chaque classe dérivée, alors je peux faire quelque chose comme DeriveClass :: Balls (); ?
@John un vecteur statique de ibase * code> s dans
ibase code> qui stocke chaque classe créée?
Je ne l'obtiens pas. Pouvez-vous expliquer pourquoi cela résout le problème de OP?
@Boithios Je ne suis pas très expérimenté en C ++, donc je ne peux pas comprendre cela. J'essaie toujours de comprendre comment le CRTP fonctionne. Pouvez-vous expliquer comment vous allez utiliser le vecteur statique?
@John je suis sûr que vous pouvez résoudre le problème de cette façon, laissez-moi un peu de temps pour écrire un code complet.
@Boithios Merci - J'ai l'impression que les réponses de la tienne et de la Smeehey vont être incroyablement intéressantes.
En lisant sur CRTP, il semble que CRTP puisse résoudre ce problème, mais c'est vraiment difficile à comprendre (pour un noob comme moi).
Vous pouvez créer un registre statique pour toutes vos classes et utiliser quelques macros d'assistance pour enregistrer de nouveaux types en informatique. Vous trouverez ci-dessous une démonstration de base de travail, qui crée 2 classes dérivées de la base. Pour ajouter de nouvelles classes, vous utilisez simplement les deux macros montrées - une à l'intérieur et une à l'extérieur de la classe. Remarque: l'exemple est très nu et ne se préoccupe pas de choses comme la vérification des doublons ou d'autres conditions d'erreur pour optimiser la clarté. Les prototypes de registres ci-dessus des classes dérivées, qui pourrait être utilisé pour la construction de copies d'autres instances par exemple. Comme alternative, demandée par le PO, vous pouvez avoir un système dans lequel les méthodes d'usine sont enregistrées au lieu de prototypes. Cela vous permet de créer des instances à l'aide d'un constructeur avec une signature particulière, plutôt que du constructeur de copie: p>
J'essaie toujours d'envelopper ma tête autour de cela: D. C'est beaucoup à prendre pour un noob
Ceci est très similaire aux "blocs statiques" dans Java, vous vous référez. Il y a beaucoup de chaudières, mais cela revient fondamentalement pour créer une instance statique de chaque classe et obtenir cette instance statique pour s'inscrire à la classe de registre. Au moment où Main code> exécute, toutes les instances statiques auront été initialisées et enregistrées.
Est-ce seulement pour VC ++?
Mais dans Xcode CLASSType donne une erreur comme "nom de type inconnu" fait-il partie de la norme?
Voulez-vous dire Xcode IDE? Les erreurs IDE ne sont pas des erreurs de compilateur, vous devez la compiler si vous n'êtes pas déjà. Me voir la démo en direct ci-dessus
Je suis en train de créer une plate-forme transversale pour iOS, Android et Visual Studio - je dois utiliser Xcode pour construire mon application en raison de certaines autres dépendances. Cela ne compilera pas s'il y a des erreurs, donc je ne suis pas sûr de ce que vous voulez dire. J'utilise Apple LLVM 7.1
Je dis que vous obtenez réellement cette erreur lors de la compilation, ou est-ce que c'est juste quelque chose que l'IDE se met en surbrillance pour vous pendant la modification? Si c'est une erreur de compilateur, et vous utilisez vraiment le code exactement comme ci-dessus, vous avez un compilateur non conforme. Si oui, pouvez-vous partager l'erreur complète?
Plus précisément, quelles lignes avez-vous ajouté?
rien. Il suffit de copier-coller, compilé pour -Std = c ++ 11 et ajouté les incluses nécessaires (iostream, chaîne et carte). - OS: Ubuntu 14.04, Compilateur: GCC.4.9.2
Désolé, cette question était pour @john
@Smeeehey - Cela fonctionne sans modification. Mais la question que j'ai est, comment puis-je utiliser cela pour créer des instances des classes dérivées?
Déclarez-les exactement comme instance code> et
autreInstance code> dans mon exemple de code. N'oubliez pas d'inclure les deux macros
register_class code> et
définir_reg_class code> selon mes exemples
@Smeeehey Ce que je veux dire, c'est, par exemple, dans la boucle dans la principale (), comment le modifieriez-vous pour créer une instance de chaque type? Comment appeleriez-vous des méthodes statiques sur chaque type?
Eh bien, vous avez déjà une instance de chaque type à votre disposition, les prototypes. Ils sont accessibles dans cette boucle principale via entrée.seconde code> (qui est un pointeur). Est-ce ce que tu veux dire?
Je ne comprends pas - normalement pour créer une instance, je fais quelque chose comme foo foo = nouveau foo (A, B);. Mais dans votre cas, vous dites que vous créez déjà une instance. Mais alors que se passe-t-il si j'ai des constructeurs plus compliqués? Et si je veux créer plus d'instances du même type? Comment puis-je vous référer au type, pour faire quelque chose comme DeriveClass BOO = NouvelleClass dérivée (A, B, C), si tout ce que je sais, c'est que chaque classe dérivée a un constructeur qui prend 3 arguments.
Ok - je vois que je peux y accéder via une entrée.seconde-> FunctionName (), etc. Mais je suis confus, comment je créerais d'autres nouvelles instances - il semble que je devrais écrire une sorte de fonctions d'assistance à l'instance pour créer une nouvelle instance d'elle-même. En outre, cela signifie que l'application ne peut exister avec zéro instance d'aucune des classes dérivées.
Mon code est censé être juste une démonstration. Avec une petite modification, il est facile de faire ce dont vous parlez. Voir cette Démo modifiée . Ici, au lieu d'enregistrer des prototypes, nous enregistrons plutôt une méthode d'usine. Ensuite, étant donné une signature de compilateur (voir exemple Classes), vous pouvez créer de nouvelles instances comme dans Main code>.
Si vous obtenez cette idée générale, vous devriez pouvoir facilement faire des choses comme ajouter de nouveaux types de constructeurs
J'ai aussi mis à jour la réponse avec ce code alternatif
@Smeeheey merci pour vos réponses - je l'apprécie vraiment! J'espère que je n'ai pas sonné Curt, essayait juste de comprendre comment tout cela fonctionne. Soufflant de l'esprit ..
Vous pouvez utiliser une usine globale de fonctions de maintenance capables de créer des objets (uniques_ptr's) de classes dérivées: Remarque: l'usine ne fournit pas de moyens d'appeler des fonctions de membre statique sans objet. < / p> p>
"Créer une carte"? Quel genre de carte? La carte de Luke Skywalker?
Pouvez-vous expliquer pourquoi vous voulez cela? Ce sera probablement plus facile de répondre de cette façon.
@Shaynehmad Je le veux afin que je puisse remplir de manière dynamique un menu, utilisé pour créer les différents types dérivés. Mais il serait très fastidieux d'attacher un bouton à chaque type dérivé, alors j'essayais de déterminer s'il y a un moyen de "refléter" toutes les classes dérivées faisant partie de l'application afin que je puisse appeler de manière dynamique toutes les méthodes, sans connaître à propos de chacun des types.
Je pense que c'est possible avec des commandes de préprocesseur ou même un script dédié. Ou des DLL externes, comme un sous-système de plug-in. Devrais-je élaborer ou n'est-ce pas ce que vous cherchez?
@Shaynehmad - J'aimerais éviter de devoir écrire un script de construction, car cela défait le but de ce que j'essaie de faire. Pouvez-vous expliquer comment je peux le faire avec des commandes de préprocesseur?
Une classe peut s'inscrire à une usine de classe. L'enregistrement peut être effectué par un constructeur d'un objet statique. Vous devrez déclarer un objet statique par classe dérivée ou utiliser une magie de modèle (CRTP) pour le déclarer automatiquement.
@ n.m. Pouvez-vous fournir un exemple de comment faire cela avec un objet statique? Je lis sur CRTP mais il est difficile de comprendre.
"Sans réellement instantifier un objet, créez un ensemble contenant tous les types." Cela ressemble beaucoup à l'enregistrement de type utilisé par Boost Serialization. Mais même si vous aviez quelque chose qui connaissait les types de toutes les classes dérivées, la seule chose qu'elle peut faire est d'appeler des fonctions statiques, car si la fonction n'est pas statique, vous devez également connaître le présent pointeur également. Les fonctions que vous appellerez-vous statique?
@Jerryjeremiah non seulement je veux appeler des fonctions statiques, mais je veux pouvoir également instancier des objets. La question du CRTP que j'ai lié ci-dessus est très proche de ce que je veux, mais je n'ai pas de façon de faire référence au "type", similaire à ce que l'on ferait dans l'objectif-c, de créer un objet sans connaître le taper.
Vous ne pouvez pas vous référer à une classe elle-même en C ++ - C ++ n'a pas de pouvoirs de réflexion. Vous devez coder les informations dont vous avez besoin et vous reporter à cela en utilisant une sorte d'identifiant. (L'identifiant est souvent une chaîne car il est pratique et lisible.)
Juste Out Sujet: N'AF NON
TYPEDEF CODE> B>
STRIT code>,
Classe code>,
Enum code>, < Code> Union code> dans C ++ , c'est un BUBDEN inutile .
N'utilisez pas d'identificateurs majuscules pour les symboles de non-préprocesseur si vous ne voulez pas avoir du mal à attraper des problèmes
Malheureusement, vous ne semblez pas avoir le problème que vous essayez de décrire. La fonction FOO () que vous avez décrite est une méthode d'instance, appelable uniquement sur des instances, et non statiquement.