Klassegröße passt nicht :D



  • Hallo Leute 🙂

    Ich habe ein kleines Problem mit virtuellen Klassen!
    Und zwar:

    Meine (in dem Beispiel total sinnlose) Basisklasse:

    class IBase
    {
    public:
    	virtual void Foo (void) = 0;
    };
    

    Meine beiden (sinnlosen) vererbten Klassen:

    class CTest1 : public IBase
    {
    private:
    	DWORD dwVar;
    public:
    	virtual void Foo (void)
    	{
    		cout << "Ich bin CTest1" << endl;
    	}
    };
    

    und

    class CTest2 : public IBase
    {
    private:
    	DWORD dwVar;
    public:
    	virtual void Foo (void)
    	{
    		cout << "Ich bin CTest2" << endl;
    	}
    };
    

    Nun das Hauptprogramm:

    int main(void)
    {
    	CTest1 Test1;
    	CTest2 Test2;
    
    	ITest* Test;
    
    	Test = &Test1;
    	Test->Foo ();
    	Test = &Test2;
    	Test->Foo ();
    
    	return 0;
    }
    

    und logischerweise wird das ausgegeben was man erwarten würde!

    Jetzt zu meinem problem :p
    Wenn ich das so schreib dann tritt eine Speicherverletzung auf und das Programm "stürzt ab"

    int main(void)
    {
    	CTest1 Test1[10];
    
    	ITest* pTest = Test1;
    
    	pTest[1].Foo ();
    
    	return 0;
    }
    

    Der Grund dafür ist mir auch klar:
    sizeof (ITest) liefert 4, allerdings sizeof (CTest1) liefert 8, denn CTest hat ja das 4Bytes große DWORD und einen Pointer (den virtual table pointer, der wie jeder Pointer in einem 32Bitsystem 4Byte groß ist)
    Sprich alle zugriffe über die Basisklasse auf geradezahlige Elemente funktioniert, aber auf die Ungeraden geht nicht!!
    Wie kann ich dieses Problem umgehen ?? Kann ich irgendwie den Compiler "zwingen" ITest 8Byte groß zu machen ??? Ich verwende Visual Studio 6 und habs dort schon mit

    #pragma pack (push, 8)
    class ITest
    {
    }
    #pragma pack (pop)
    

    versucht, aber ohne Erfolg!

    Ich muss aber Arrays von den abgeleiteten Klassen über einen Basisklassenzeiger ansprechen können!! und die haben aber nunmal alle einen Member mehr !
    Habt ihr dafür ne Lösung ??

    Schonmal danke im vorraus !!

    Gruß
    Xatian



  • Spontanantwort ohne genauer in den Quellcode geschaut zu haben:

    Könnte die automatische Strukturausrichtung (padding) die Ursache sein?



  • Ne daran kanns unmöglich liegen! Mein Compiler verschwendet keinen Platz weil ein DWORD und ein Pointer nunmal 8Byte brauchen ... hab ich aber eh beim ersten Post schon geschrieben 🕶



  • Hallo

    das was du machst ist meiner Meinung schlicht undefiniert. Du kannst nunmal ein Array von Ctest1 nicht als Array von IBase behandeln. Selbst wenn du durch Tricks eine scheinbare Lösung erreichst, ist die weder stabil, standardkonform noch portabel.
    Du solltest eher an den Konzept an sich arbeiten.

    bis bald
    akari



  • Ich nehm mal an Dir gehts ums serialisieren / streamen ....

    Wir haben aehne Problemstellungen (unterschiedliche Typen von telegrammen muessen in eine datei, binaer) und loesen das mittels strukturen ....

    die struktur hat am anfang ne Laengenangabe (Byte) und dann erst die Verwaltungs und nutzdaten. damit kann man die strukturen serialisieren ohne zu wissen was es eigentlich genau fuer eine struktur ist.
    Der zugriff erfolgt dann ueber wrapperklassen die man einfach drueberlegt.

    Die meisten Protokolle in der elektronic / IT machen es aehnlich ...

    Ciao ...


Log in to reply