2016-07-23 11 views
0

Ich wundere mich darüber. Ich habe versucht, eine C++ - Klasse zu schreiben, um ein polymorphes Objekt zu serialisieren. Das heißt, ich habe einenWie implementieren Sie eine gekapselte Serialisierung in C++ ohne ein Makro?

template<class T> 
class PolymorphicSerializable { 
    ... 
}; 

, die sich von der Wurzel einer polymorphen serializable CRTP Hierarchie geerbt werden kann (das heißt, „T“ wird, daß Wurzelklasse). Es enthält eine "statische" Membervariable, die eine Zuordnung von Klassennamen zu Factory-Funktionen oder Funktionsobjekten darstellt, die beim Laden neue Instanzen der abgeleiteten Klassen erstellen können (der Name der Klasse wird zusammen mit den Daten gespeichert).

Das Problem, das ich habe, ist dieses statische Element muss natürlich initialisiert werden. Die Art, wie ich das gerade mache, besteht darin, einige Makros zu verwenden, um diese Textplatte auszufüllen. Das Problem ist jedoch, dass diese statisch initialisieren wir die Template-Parameter natürlich brauchen, und wenn „T“ ist eine Vorlageninstanz (dh Wurzelklasse ist eine Vorlageninstanz) Ich laufe in so etwas wie

MACRO_FOR_INITIALIZING_STATIC_MEMBER(SomeClass<int, int>) 

(nicht sein tatsächlicher Name) und der C++ - Präprozessor mag dies wegen des Kommas nicht. Putting

MACRO_FOR_INITIALIZING_STATIC_MEMBER((SomeClass<int, int>)) 

nicht funktioniert, entweder weil ein Template-Argument (das heißt „T“ von PolymorphicSerializable) nicht in Klammern eingeschlossen werden und dass klammerten Version ist das, was als Template-Argument endet.

Was kann dagegen getan werden? Es muss eine Möglichkeit geben, das Implementierungsdetail der Klassenzuordnung wegzukapseln - aber wie? Gibt es sogar einen Weg, es ohne Makro zu machen?

+2

Es könnte Sie interessieren, über die Existenz von 'variadic Makros' (C++ 11) zu wissen, die dieses spezielle Problem lösen können: '#define MACRO (...) doStuff (__ VA_ARGS __)' –

Antwort

0

Neben variadische Makros, wie durch einen Kommentar zu Ihrer Frage vorgeschlagen, könnten Sie das statische Element in einer Getter-Funktion wickeln, da sie das Requirment entfernt Raum für das statische Element der Zuweisung separat:

template<class T> 
class PolymorphicSerializable { 
    typedef SomeType<T> StaticInstanceType; 
    static StaticInstanceType& getContext() { 
     static StaticInstanceType instance; 
     return instance; 
    } 
}; 

Und benutze den Getter überall.