2009-04-13 16 views
2

J'ai lu un peu sur ce que sont les métaclasses, mais j'aimerais savoir si elles peuvent être réalisées en C++.Comment puis-je implémenter des métaclasses en C++?

Je sais que la bibliothèque Qt utilise MetaObjects, mais elle utilise une extension de C++ pour y parvenir. Je veux savoir si c'est possible directement en C++.

Merci.

Répondre

1

Il est possible de créer des méta-classes, mais C++ n'est pas à ce sujet, il s'agit d'implémentations statiquement basées sur la compilation, pas de flexibilité d'exécution. Cela dépend si vous voulez des Meta-Classes avec des méthodes ou juste des Meta-Classes avec des données, les classes Data peuvent être implémentées avec des constructions Boost comme boost :: any, et si vous voulez des Classes avec des méthodes, vous pouvez utiliser boost :: bind pour lier des méthodes à l'objet, ou vous pouvez les implémenter vous-même avec une interface de point d'entrée unique comme les objets COM.

Cependant, le "vrai" C++ consiste à utiliser des génériques afin que tout puisse être déterminé au moment de la compilation, pour de meilleures performances. Pour être honnête, j'ai vu très peu de systèmes, bien que j'en ai vus, qui nécessitent vraiment une flexibilité d'exécution, dans la plupart des cas les objets naissent et meurent de la même classe, ou au moins assez pour dépenser 95% vie comme une seule classe une fois qu'ils sortent de leur usine.

Ainsi, dans de nombreuses situations, on paie trop pour les méta-classes d'exécution. Bien sûr, il ya l'école de pensée que cela fournit de meilleures performances de développement, mais dans de nombreuses situations, chaque ligne de code sera exécutée sur le matériel quelques centaines de millions de fois plus que le temps qu'il a fallu pour l'écrire. Vous pouvez donc penser que les classes de compilation et d'exécution sont payantes ou locatives pour toujours. Personnellement, j'aime payer à l'avance.

3

Plusieurs des motifs du livre "Design Patterns" de Gamma, et al ont des caractéristiques similaires au concept de la métaclasse. Le modèle "Stratégie" vous permet de personnaliser le comportement de l'objet lors de la création, par exemple. L'idiome lettre-enveloppe est un autre match proche. Cependant, vous ne pouvez pas personnaliser l'interface de la classe.

Dans COM, l'interface IDispatch permet d'ajouter dynamiquement des méthodes/attributs à un objet lors de l'exécution. Cela signifie abandonner les appels de méthode C++ standard, cependant. Chaque appel passe par la même méthode, qui prend un index ou une clé de chaîne dans une table de méthode/propriété maintenue et tous les paramètres doivent être passés en tant que tableau d'objets. En utilisant ces deux techniques, vous pouvez obtenir la flexibilité des métaclasses, mais c'est un slog beaucoup plus difficile, car il n'a pas de valeur syntaxique ou d'aide à l'exécution/au compilateur.

Dave

1

Peur pas ... Au moins pas nativement. Avoir une métaclasse nécessiterait généralement qu'il y ait un objet d'exécution représentant une classe, comme c'est le cas en Java.

En C++, les classes n'ont pas de représentation d'exécution. Leurs manifestations se produisent dans des choses comme la table virtuelle. Mais à bien des égards, ils fonctionnent comme des fonctions C avec tout le fonctionnement de la POO presque comme un code de colle. Cela étant dit, il existe des modèles de POO pour beaucoup de choses que vous pourriez vouloir implémenter avec une métaclasse dans d'autres langages. Vous pouvez également "simuler" votre propre système d'objets.

3

Si la définition de travail de métaclasse est « une entité linguistique dont instanciations sont eux-mêmes des classes », puis génériques sont métaclasses en C++:

#include <iostream> 
using namespace std; 

template <typename T> 
class Meta { 
public: 
    Meta(const T&init) : mData(init) {} 
// ... 
private: 
    T mData; 

}; 

int main(int, char **) { 
    cout << "The size of Meta<double> is " << sizeof(Meta<double>) << endl ; 
    return 0; 
} 

L'utilisation de Meta < à double > dans la ligne antépénultième oblige le compilateur pour instancier la classe Meta <double>; l'opérateur sizeof opère sur Meta, démontrant ainsi que ce n'est pas simplement du sucre sémantique et que la classe a été instanciée. Le programme est complet même si aucun objet de type Meta n'est instancié.

3

C++ N'a pas de support intégré pour les méta-classes (pas de la manière Python/Objective-C), cependant vous pouvez imiter manuellement le comportement des méta-classes. Les bases sont assez simples, vous créez une classe supplémentaire avec une durée de vie plus longue (Singleton, objet statique ou le Construct On First Use Idiom) qui est capable de créer et de manipuler sa classe correspondante. (En Objective-C, la méta-classe contient généralement des variables membres «statiques», les routines allocation/désallocation de mémoire et cetera). Ce que Qt a fait, c'est qu'ils ont pris le concept de méta-classes et l'ont modifié pour qu'ils puissent supporter une certaine forme de Reflection (et RTTI sur les systèmes qui ne le supportent pas). Implémenter cela nécessitera beaucoup de magie des macros ou un compilateur personnalisé (comme ils ont choisi d'utiliser).En général, cependant, la plupart des fonctionnalités d'une méta-classe régulière sont déjà fournies par le langage C++; juste sous une forme différente. Et vraiment, la seule raison pour laquelle vous voudriez que les méta-objets soient à des fins de réflexion, il existe différentes façons d'implémenter la réflexion en C++ comme décrit dans this document. En outre, si vous êtes vraiment sur un système de méta-classe Objective-C-style, je ne connais pas de bibliothèques qui le font mais il pourrait très bien être. D'un autre côté, rouler le vôtre ne devrait pas être si difficile non plus.