8
votes

Exécutez le code avant chaque fonction d'appel pour une classe en C ++

Je voudrais exécuter du code (peut-être une fonction) juste avant chaque fonction d'appel pour une classe et toutes les fonctions des classes qui héritent de cette classe. J'aimerais faire cela sans modifier réellement toutes les fonctions, est une chose si possible?

Je me contenterais d'avoir une fonction appelée comme première instruction de chaque appel de fonction au lieu d'être appelée juste avant.


0 commentaires

9 Réponses :


9
votes

AspectC ++ est ce que vous voulez. Je ne l'ai pas utilisé moi-même, mais Programmation orientée sur les aspects Paradigm tente de résoudre ce problème problème.


1 commentaires

Je suis strictement contre des aspects, parce que vous ne savez jamais combien coûte qu'ils apportent à votre code et à quel code ils se développeront. Il n'est pas non plus clair comment les déboguer en C ++, car ils produisent efficacement du code et transformer entièrement les points d'entrée de vos fonctions.



1
votes

Le moyen quelque peu gênant où construire une classe d'emballage qui prend un objet de votre type de base et appelle la fonction environnante, puis la fonction que vous vouliez appeler. Ce serait quelque chose comme un décorateur .


0 commentaires

0
votes

Cela ressemble à ce que fait un profileur. Avez-vous examiné la source des outils de profilage?


1 commentaires

Cela ressemble plus à la programmation contractuelle. Vérification des conditions préalables et post-post pour valider que le contrat n'a pas été brisé.



3
votes

Je suggérerais d'utiliser l'interface non virtuelle idiome. Toutes les fonctions publiques sont non virtuelles. Toutes les fonctions virtuelles sont protégées ou privées. Les membres du public déléguent les appels aux membres virtuels et sont généralement mis en œuvre comme des fonctions en ligne.

C'est la façon dont iostreams sont implémentés dans STL. Vous pouvez en savoir plus à ce sujet à C ++ Wikibooks .

Intention: à modulariser / refacteur commun avant et après des fragments de code (par exemple, vérification de l'invariant, acquérir / relâcher des verrous) pour une hiérarchie de classe entière à un endroit.

Cordialement,
Ovanes


0 commentaires

1
votes

Le mieux que vous puissiez faire est de déclarer un ensemble de fonctions virtuelles telles que protégées et que les développeurs hérissent de la classe remplacent les fonctions virtuelles. L'interface utilisée par la classe de base peut être publique, qui exécute le code souhaité avant de transmettre des informations sur la méthode virtuelle protégée.

Par exemple: P>

class Base {
  public:
    void MyMethod(void) { /* Insert code here */ YourMethod(); }
  protected:
    virtual void YourMethod(void) {}
};


1 commentaires

Je peux penser à d'autres moyens qui n'impliquent pas d'envahir la classe testée.



2
votes

Une autre chose que vous pourriez envisager consiste à utiliser quelque chose comme l'emballage [Boost / C ++ 0x] Shared_PTR, où vous appelez votre fonction personnalisée sur la surcharge '->' avant de renvoyer le pointeur d'instance de classe. Cela implique la modification d'une utilisation mais pas de la classe sous-jacente, et je l'ai utilisé à quelques reprises pour atteindre le même effet. Juste une autre pensée.


0 commentaires

3
votes

Ce qui suit pourrait être un peu de surpoids - mais que diriez-vous?

http://msdn.microsoft.com/en-us/library /c63a9b7h.aspx


0 commentaires

0
votes

Vous pouvez également faire cela avec le Modèle de modèle curieusement récurrent (CRTP) .


0 commentaires

0
votes

Utilisation g ++ , vous pouvez utiliser l'option -pg pour les unités de compilation respectives, ce qui rend le compilateur générer un appel à la fonction mcount Au début de chaque fonction. Mcount est généralement fourni par des outils de profilage tels que GPROF , mais vous pouvez également la mettre en œuvre vous-même. Vous devez cependant vous assurer que

  • mcount a une liaison C (et n'est pas c ++ - Nom de style-mangelé de style), c'est-à-dire en la mettant en la mise en oeuvre en tant que fonction C et en compilant avec un compilateur PURE C comme GCC .
  • L'unité de compilation contenant mcount n'est pas compilée avec -pg .

1 commentaires

Utilisez extern "C" mot-clé pour créer C ++ compiler avoir la liaison C correcte C pour MCount . Comme dans externe "c" vide mcount (...) . Pas besoin d'utiliser un compilateur C uniquement. PS, GCC passera heureusement au mode C ++ si vous avez passé un fichier avec une extension du CPP.