3 Stimmen

Wie man grundlegendes Mixin-Verhalten in C++ darstellt

Betrachten Sie eine bestehende C++-Klassenhierarchie: eine Wurzelklasse, viele Unterklassen, die einen direkten azyklischen Graphen bilden.

Ich möchte der Root-Klasse eine Methode hinzufügen und sie möglicherweise in einigen untergeordneten Klassen außer Kraft setzen. Aber das Problem ist, dass es mir verboten ist, diese bestehenden Klassen zu ändern (Bibliothek eines Drittanbieters, Projektpolitik, geschlossene Quellen, usw.).

Eine Mixin/Erweiterungsklasse wäre dann eine gute Lösung. Aber das ist in C++ nicht trivial machbar.

Die schnelle und schmutzige Lösung besteht darin, eine Funktion zu schreiben, die auf den Typ des Objekts mit die dynamisch_gecastet Operator und die Ausführung des gewünschten Codes für jeden Typ der Hierarchie. Dies ist jedoch eine schlechte Praxis, da es fehleranfällig ist, die Kapselung bricht und zukünftige Änderungen nicht sicher unterstützt.

Ich denke darüber nach, irgendwo eine Art Hash-Tabelle mit der Definition zu führen {rtti type id, aufzurufende Funktion} ", und verwenden Sie dies als a gefälschte VT-Tabelle für die Funktion, die ich schreiben und außer Kraft setzen möchte. Aber ich bin nicht sicher, ob es besser wäre...

Haben Sie eine andere Idee? Laufzeit-VTable-Änderung? Lösung für die Meta-Programmierung von Vorlagen? Andere?

Vergessen Sie nicht: Ich kann die ursprünglichen Klassen definitiv nicht ändern (weder Header noch Implementierung).

2voto

Matthieu M. Punkte 266317

Wenn Sie die ursprüngliche Hierarchie nicht ändern können, ist die Meta-Programmierung von Vorlagen wahrscheinlich nicht hilfreich. Denken Sie daran, dass sie auf Informationen zur Kompilierzeit basiert.

Ändern der vtable scheint wie eine extrem schlechte Idee, es ist offensichtlich nicht portabel und voraussetzen, dass Sie etwas wissen, seine physische Anordnung ... selbst wenn Sie es richtig bekommen, es wird ein Alptraum der Wartung sein.

Ich mag die std::map<type_info, Func> Idee. std::type_info::before bietet Ihnen alles, was Sie für die Umsetzung benötigen (verlassen Sie sich nicht auf den Namen oder die Adresse).

2voto

Eigentlich schreibe ich eine Bibliothek, die genau das tut: ermöglicht es Ihnen, zu komponieren und zu ändern Typen aus bestehenden Klassen zur Laufzeit, mit dem Preis der nicht in der Lage, die Methoden als ... äh Methoden, sondern als externe Funktionen mit ersten Argument aufrufen this . Es ist nicht eingreifend, so dass Sie die bestehenden Klassen in keiner Weise ändern müssen.

Code: https://github.com/iboB/boost.mixin

Doc: http://ibob.github.io/boost.mixin/

Ich hoffe, es hilft.

PS. Es heißt Boost.Mixin, weil ich beabsichtige, es bei Boost einzureichen, aber es ist noch nicht Teil von Boost.

1voto

wilhelmtell Punkte 55189

Schreiben Sie eine freie Funktion.

void vfunc(base& param);

// ...
base b;
vfunc(b);

deriv0 d0;
vfunc(d0);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X