Basteln einer eigenen Template-Containerklasse



  • slaughter schrieb:

    @ CStoll: Vielen Dank erstmal für die Antwort! aber nochmal zum ersten: habe da mal was gelesen von

    template<>
    myContainer::myContainer()
    

    oder so ähnlich. wird anscheinend nicht von allen compilern unterstützt, da es erst neu in den Standard aufgenommen wurde, aber es ist jedenfalls Ansi-C++. kann es sein, dass sowas den gleichen zweck erfüllt?

    Nein, das ist eine Template-Spezialisierung (und da müsstest du noch angeben, für welchen Typ du das spezialisieren willst).

    und das mit dem auslagern der templatemethoden in eigene cpp files war mir nicht bekannt aber dafür gibts dann wohl die PCHs.

    Inwieweit dir vorcompilierte Header bei Templates weiterhelfen, bin ich nichtmal so sicher.

    (im ANSI-Standard gibt es für so eine Trennung zwar das Schlüsselwort 'export' - aber das wird von kaum einem Compiler wirklich unterstützt).

    drittens: genau das ist das problem: es werden dynamische arrays verwendet. jetzt müsste ich den copy-ctor und den operator= eben nochmal schreiben (fast der gleich quelltext) und das würde sich schon fast mit der one-def-rule überschneiden. warscheinlich wärs dann sinnvoller eine virtual methode in der basisklasse bereitzustellen, die sowas erledigt, oder jeweils die ctoren der basisklasse aufzurufen.

    Solange die abgeleitete Klasse keine eigenen dynamischen Elemente anlegt und verwaltet, stört das überhaupt nichts. Die default-generierten Methoden rufen jeweils die entsprechenden Funktionen der Basisklasse und der eigenen Member auf - und die Basismethoden sind dann dafür zuständig, die dynamischen Arrays zu verwalten.



  • CStoll schrieb:

    drittens: genau das ist das problem: es werden dynamische arrays verwendet. jetzt müsste ich den copy-ctor und den operator= eben nochmal schreiben (fast der gleich quelltext) und das würde sich schon fast mit der one-def-rule überschneiden. warscheinlich wärs dann sinnvoller eine virtual methode in der basisklasse bereitzustellen, die sowas erledigt, oder jeweils die ctoren der basisklasse aufzurufen.

    Solange die abgeleitete Klasse keine eigenen dynamischen Elemente anlegt und verwaltet, stört das überhaupt nichts. Die default-generierten Methoden rufen jeweils die entsprechenden Funktionen der Basisklasse und der eigenen Member auf - und die Basismethoden sind dann dafür zuständig, die dynamischen Arrays zu verwalten.

    oh genau, das hätte ich jetzt fast übersehn 🙄
    natürlich wird in der abgeleiteten klasse kein speicher mehr auf dem heap angefordert, dann würd's natürlich gehen. Danke für den Tip 👍



  • habe jetzt ein weiteres problem, wobei ich glaube, dass es in C++ nicht umsetzbar ist: ich habe jetzt der basisklasse einen member maxsize verpasst. der wird bei einer methode benötigt, die virtual ist und daher in allen abegeleiteten klassen existiert. maxsize wird weiterhin in jeder abgeleiteten klasse überschrieben, und benötigt für die eben erwähnte methode ja einen this zeiger, kann also nicht statisch sein. const kann es aber auch nicht sein, weil man es sonst im elementinitialisierer des ctors initialisieren müsste, da wirds aber schon wieder gebraucht. zum besseren verständnis mal ein bsp:

    class myContainer
    {
    private:
        const size_t maxsize;
        size_t m_size;
    public:
        myContainer(const size_t size)
        : maxsize(1<<10), m_size(std::min(maxsize, size))
        {};
    };
    

    geht nicht, maxsize müsste da static sein!

    class myContainer
    {
    private:
        size_t m_size;
        static const size_t maxsize = 1<<10;
    //...
    };
    

    geht auch nicht, ich will maxsize ja in jeder abgeleiteten klasse haben.



  • Wieso sollte der erste Teil nicht gehen? Btw, was zwingt dich dazu, maxsize static zu definieren?



  • CStoll schrieb:

    Wieso sollte der erste Teil nicht gehen? Btw, was zwingt dich dazu, maxsize static zu definieren?

    der compiler, er sagt es MUSS statisch sein, wobei ich dann die virtual methode vergessen kann ...
    btw ich verwende die IDE visual studio 2005 express falls das weiterhilft



  • In den obigen Code-Schnipseln sehe ich keinen Grund, das static zu definieren. Wo und wie setzt du denn maxsize ein? (btw, static und virtual widersprechen sich ein wenig ;))



  • CStoll schrieb:

    In den obigen Code-Schnipseln sehe ich keinen Grund, das static zu definieren.

    glaub mir, ich auch nicht. aber leider macht compiler dann mucken...

    CStoll schrieb:

    Wo und wie setzt du denn maxsize ein?

    eine virtual methode der basisklasse setzt es ein. das element maxsize hat in jeder abgeleiteten klasse einen anderen wert und somit arbeitet die virtuelle methode immer mit dem zur klasse passenden maxsize

    CStoll schrieb:

    (btw, static und virtual widersprechen sich ein wenig ;))

    eben genau deswegen darf es ja nicht statisch sein!



  • CStoll schrieb:

    In den obigen Code-Schnipseln sehe ich keinen Grund, das static zu definieren. ...

    Ich schon :p 😃 : Er will es in der Deklaration initialisieren und das geht IIRC nur mit "const static"s, oder ?

    Wie wärs mit

    class myContainer
    {
    private:
        size_t m_size;
        virtual size_t maxsize() { return 1<<10; }
    ...
    

    ist jedenfalls const und virtual UND in der Deklaration definiert ...

    Gruß,

    Simon2.



  • Simon2 schrieb:

    CStoll schrieb:

    In den obigen Code-Schnipseln sehe ich keinen Grund, das static zu definieren. ...

    Ich schon :p 😃 : Er will es in der Deklaration initialisieren und das geht IIRC nur mit "const static"s, oder ?

    jo genau, das hatte ich vor. oder wenns sein muss auch noch im elementinitialisierer, aber wirklich nur wenns nich anders geht (wobei nichtmal das geht, also dort initialisieren und direkt dannach noch verwenden, bevor der eigentlich block anfängt)...
    von daher glaube ich auch, dasses nur mit static const's geht.

    Simon2 schrieb:

    Wie wärs mit

    class myContainer
    {
    private:
        size_t m_size;
        virtual size_t maxsize() { return 1<<10; }
    ...
    

    ist jedenfalls const und virtual UND in der Deklaration definiert ...

    Vielen dank für den vorschlag 👍 👍 👍
    so muss ich zwar die methode auch jedesmal überschreiben aber das wars dann auch schon. da das mit der konstante nicht geklappt hat, hätte ich fast die besagte methode aus der basisklasse jedesmal neu geschriben und das wär unfug!



  • Hupps,

    natürlich ein const vergessen:

    ...
        virtual size_t maxsize() const { return 1<<10; }
    ...
    

    Allerdings musst Du mit der Technik ein wenig aufpassen, denn maxsize kannst Du nun natürlich nicht mehr "referenzieren" (also z.B. an eine Funktion übergeben, die einen "size_t const*" erwartet - bei "size_t const&" bin ich mir gerade nicht sicher)...

    "Initialisierungsliste" wäre natürlich auch noch eine Idee gewesen (auf die ich nicht gekommen bin)... aber da wird's dann mit dem Überladen in abgeleiteten Klassen häßlich....

    Gruß,

    Simon2.


Anmelden zum Antworten