Erben von einem templatisierten Objekt



  • Thx 🙂

    Kann mir vielleicht noch jemand sagen unter welchen Stichworten ich mehr Infos hierfür finden könnte?

    Unter "Inherit template" finde ich verständlicherweise nichts :>



  • @theliquidwave Das ist nicht standardkonform.
    @Sharkbyte Wo hat dein Problem überhaupt irgendetwas mit Vererbung zu tun? 😕 "Das struct als ganzes füllen" geht so leider nicht. Der Compiler kann hier nach belieben Padding einbauen. Es ginge höchstens, wenn du vorher auch aus so einem struct die Daten in ein char Array kopiert hättest, und sie jetzt wieder zurückkopierst. Aber was soll das überhaupt sein? Ein struct mit 3-char arrays wirkt auf den ersten Blick erstmal.. sinnlos. 😉
    PS: Deine Basis-Klassen haben einen virtuellen Destruktor?



  • cooky451 schrieb:

    @theliquidwave Das ist nicht standardkonform.

    Aber man kann es standardkonform machen.

    std::memset(static_cast<irgendwas*>(this), 0, sizeof(struct irgendwas));
    

    (oder so in der Art, will das jetzt nicht testen)



  • Wenn dann reinterpret_cast



  • Nathan schrieb:

    Wenn dann reinterpret_cast

    Wie das?


  • Mod

    conforama schrieb:

    cooky451 schrieb:

    @theliquidwave Das ist nicht standardkonform.

    Aber man kann es standardkonform machen.

    Nur wenn jeder Member separat initialisiert wird.

    conforama schrieb:

    std::memset(static_cast<irgendwas*>(this), 0, sizeof(struct irgendwas));
    

    (oder so in der Art, will das jetzt nicht testen)

    So geht es jedenfalls nicht. memcpy&co. können nur auf nicht-Basisklassenobjekte angewendet werden.



  • cooky451 schrieb:

    Es ginge höchstens, wenn du vorher auch aus so einem struct die Daten in ein char Array kopiert hättest, und sie jetzt wieder zurückkopierst. Aber was soll das überhaupt sein? Ein struct mit 3-char arrays wirkt auf den ersten Blick erstmal.. sinnlos. 😉

    Hiho,

    Das Struct hat jeweils um die 30-40 char arrays und davon gibt es historisch bedingt in diesem Projekt eine Menge.

    Und ja, Ausgangssituation ist, ich kopiere den Inhalt eines solchen Structs, schick die Zeichenkette über ein Telegramm an einen anderen Prozess um ihn dort wieder in das gleiche struct zu schieben.

    Es ist jetzt aber doch so wie du sagtest, beim Erstellen und Initialisieren der Klasse wird das char array nicht ganz korrekt drüber gelegt.
    Kann man das irgendwie lösen?



  • Gerade hat sichs gelöst.

    Aber zum Thema Destruktor, muss ich die char Arrays einzeln löschen?



  • Sharkbyte schrieb:

    Aber zum Thema Destruktor, muss ich die char Arrays einzeln löschen?

    Nein, du musst nur Speicher mit delete freigeben, den du mit new angefordert hast und selbst verwaltest. Dank RAII kommt dieser Fall idealerweise recht selten vor.



  • Sharkbyte schrieb:

    Es ist jetzt aber doch so wie du sagtest, beim Erstellen und Initialisieren der Klasse wird das char array nicht ganz korrekt drüber gelegt.
    Kann man das irgendwie lösen?

    Vielleicht so:

    class tester : public structtemplatetest< irgendwas >
    {
    public:
        tester( const char* s )
        {
            assert( s );
            typedef std::char_traits< char > Traits;
            std::size_t len = Traits::length( s ) + 1; // + 1 wg. char(=) am Ende
    
            std::size_t l = std::min(sizeof(eins), len);
            Traits::copy( eins, s, l );
            if( (len -= l) == 0 )
                return;
            s += l;
    
            l = std::min(sizeof(zwei), len);
            Traits::copy( zwei, s, l );
            if( (len -= l) == 0 )
                return;
            s += l;
    
            l = std::min(sizeof(drei), len);
            Traits::copy( drei, s, l );
            if( (len -= l) == 0 )
                return;
            s += l;
    
            std::cerr << "Rest: [" << s << "] konnte nicht uebernommen werden" << std::endl;
        }
    };
    


  • Sharkbyte schrieb:

    Jetzt würde ich aber gerne das struct als ganzes füllen, z.B. mit einem char array das ich dem Konstruktor mitgebe.

    Du kannst das struct als ganzes füllen, indem du einfach den (automatisch generierten) Zuweisungsoperator verwendest.
    Bzw. du könntest "structtemplatetest" auch einen entsprechenden Konstruktor verpassen, so dass "irgendwas" gleich in der Initializer-Liste initialisiert wird.

    So in der Art:
    http://ideone.com/5ftTxL

    #include <iostream>
    
    struct clBaseSegment {};
    
    template <class T> 
    class structtemplatetest : public clBaseSegment, public  T{ 
    
    }; 
    
    typedef struct irgendwas{ 
    char eins[5]; 
    char zwei[5]; 
    char drei[5]; 
    }irgendwas; 
    
    class tester : public structtemplatetest<irgendwas>{ 
        public: 
         tester(irgendwas const& iw)
         {
            *static_cast<irgendwas*>(this) = iw;
         }; 
    };
    
    int main()
    {
        irgendwas iw;
        iw.eins[0] = 'a';
        iw.zwei[0] = 'b';
        iw.drei[0] = 'c';
        tester tt(iw);
        std::cout << tt.eins[0] << " " << tt.zwei[0] << " " << tt.drei[0] << "\n";
    }
    

    Das Problem reduziert sich auf jeden Fall darauf irgendwie "irgendwas" "am Stück" zu initialisieren/zuzuweisen. Dass hierbei vererbt wird und Templates im Spiel sind macht keinen Unterschied.

    Falls das nicht das ist was du willst bitte beschreib nochmal genauer wie du das "irgendwas" Struct initialisieren/zuweisen willst.

    ps: der ; am Ende des "tester" Konstruktors ist natürlich überflüssig - ich hab den einfach doof mitkopiert, fällt mir erst jetzt auf.


Anmelden zum Antworten