Frage zum Design einer varchar Klasse



  • Hi,

    für meine DB Bibliothek möchte ich eine "varchar" Klasse zur Verfügung stellen. Der Benutzer kann dann in seinem DB Objekt Member vom Typ "varchar" anlegen. Diese (und natürlich die anderen Member) können dann über eine Schnittstelle (Serializer/Atomizer-Pattern) auf der DB modifiziert werden. Diese Schnittstelle kann natürlich auch für andere Dinge benutzt werden, will sagen, sie ist generisch.

    Der Aspekt, der mich beschäftigt, ist, wie ich dem varchar seine Größe mitteile. In meinem ersten Ansatz dachte ich, es ist eine gute Lösung daraus eine template Klasse zu machen:

    template < unsigned int C >
    class varchar
    {
    public:
      unsigned int capacity() { return C; }
    };
    

    Durch den template Parameter könnte ich schon bei der Deklaration angeben welche Größe der varchar auf der DB haben wird:

    class Person
    {
    public:
      varchar<64> name;
      varchar<256> address;
    };
    

    Für die oben erwähnte Serializer Schnittstelle benötige ich natürlich eine nicht template basierte Basisklasse:

    class atomizer
    {
    public:
      //...
      virtual serialize(const varchar_base &x) = 0;
      virtual deserialize(varchar_base &x) = 0;
    };
    

    Dann müsste ich eine virtuelle Basisklasse varchar_base zur Verfügung stellen und von dieser meine template varchar Klasse ableiten.

    Die zweite Lösung ist, eine nicht template Klasse varchar zu schreiben, bei der die Größe als Parameter im Konstruktor übergeben wird:

    class varchar
    {
    public:
      explicit varchar(unsigned int capacity);
    
      unsigned int capacity() const;
    
    private:
      unsigned int capacity_;
    };
    

    Hier finde ich die Schreibweise bei der Benutzung "nicht elegant", habe mir aber eine virtuelle Klasse gespart (Stichwort Laufzeit):

    class Person
    {
    public:
      Person()
        : name(64)
        , address(256)
      {}
      varchar name;
      varchar address;
    };
    

    Welche Lösung ist hier zu bevorzugen? Interessant finde ich den Vergleich zwischen Benutzung und Implementation (template und virtuell gegen non-template und unelegant).

    Bin auf eure Meinungen und Hinweise gespannt!

    Gruß,
    zussel



  • Wieso eigentlich eine virtuelle Basisklasse?

    Und wenn du von Laufzeit redest:
    Eine Basisklasse zu haben sollte mehr oder weniger kostenlos sein.

    Da ist das Festlegen der Größe zur Laufzeit performancetechnisch viel kritischer, weil du dann vermutlich dynamisch speicher allozieren musst.

    Die Frage ist: Gibt es Anwendungsfälle, in denen die Größe zur Laufzeit erst festgelegt wird / bekannt ist?
    Wenn ja, dann brauchst du auf jeden fall die zweite Variante.

    Du könntest auch eine Basisklasse erstellen und beide Varianten implementieren und jeweils davon erben.



  • Hi Q!

    Q schrieb:

    Wieso eigentlich eine virtuelle Basisklasse?

    Hmm, ich dachte zuerst es wäre zwingend notwendig. Auf Deinen Kommentar hin habe ich meine Implementation mal entsprechend geändert. Und es geht (bis jetzt) auch ohne. 🙂 Mal sehen wie meine Serializer Klassen darauf reagieren.

    Q schrieb:

    Und wenn du von Laufzeit redest:
    Eine Basisklasse zu haben sollte mehr oder weniger kostenlos sein.

    Hierbei ging es mir um die vtable.

    Q schrieb:

    Da ist das Festlegen der Größe zur Laufzeit performancetechnisch viel kritischer, weil du dann vermutlich dynamisch speicher allozieren musst.

    Mein erster Ansatz sieht erstmal einen std::string als Member. Da brauch ich erstmal nichts zu allozieren, sondern nur die Größe prüfen.

    Q schrieb:

    Die Frage ist: Gibt es Anwendungsfälle, in denen die Größe zur Laufzeit erst festgelegt wird / bekannt ist?
    Wenn ja, dann brauchst du auf jeden fall die zweite Variante.

    Ja, wird es definitiv geben.

    Q schrieb:

    Du könntest auch eine Basisklasse erstellen und beide Varianten implementieren und jeweils davon erben.

    Diese Variante war mein Ziel und werde ich jetzt so umsetzen.

    Danke für Deine Antwort. Hat mich weitergebracht.

    Gruß,
    zussel


Anmelden zum Antworten