2009-05-11 2 views
0

In C++ ist das Problem einfach.C++ RTTI Vererbung bewirkt, dass die Klassengröße zunimmt

Ich habe 2 Klassen eine das andere im Rahmen ihrer Umsetzung enthält.

struct A 
{ 
    void do_something() 
    { 
    }; 
}; 

struct B 
{ 
    A obj_A; 
    void hello_world() 
    { 
    }; 
}; 

Das Problem ist jetzt, dass Struktur B ein Byte größer ist, wenn ein Teil von B ist, wenn ein I sizeof (B) und Objekt vom Typ B. A tun, ist 100% nur einzige nicht-virtuelle gehen schließen Mitglieder (keine virtuelle Tabelle erforderlich) und es ist keine Typid-Prüfung erforderlich. Gibt es eine Möglichkeit (wie eine Compiler-Direktive), das nicht benötigte Byte vollständig aus B zu entfernen, aber trotzdem die Mitgliedsfunktion von A durch B zu erreichen?

Ich kann nur davon ausgehen, das zusätzliche Byte ist ein Compiler char * zu A den Namen "A" hinzugefügt, aber alle anderen Ideen können hilfreich sein.

+0

Wenn Ihr Compiler g ++, versucht Deaktivieren von RTTI durch Kompilieren mit 'g ++ -fno-rtti'. Wenn das Problem weiterhin besteht, geben Sie bitte eine vollständige C++ - Quelldatei an, die das Problem aufweist, und ich werde sehen, welche Größe mein Compiler ergibt. – pts

+1

FWIW: Ich habe versucht, den Code mit g ++ (Version 4.2.4) mit und ohne obj_A Mitglied kompilieren, mit und ohne RTTI aktiviert ist, und jedesmal, wenn ich bekam sizeof (B) == 1. So scheint es einige Informationen fehlen von deiner Frage. –

Antwort

2

Sie erwähnen Compiler leider nicht.

Wie auch immer, in dem Code, den Sie posten, ist die Klasse A ein Kandidat für die "Empty Base Class Optimization". Dies ist ein Teil des C++ - Standards, der besagt, dass eine Basisklasse ohne Membervariablen so optimiert werden kann, dass sie keine Bytes aufnimmt.

B muss nach dem C++ - Standard Platz einnehmen, da es mindestens ein Member (nämlich obj_A) enthält.

Sie können die Mitgliedsfunktion von A direkt von B aus aufrufen, indem Sie do_something() aufrufen. Keine Magie ist nötig.

+0

Wird Klasse A wirklich als Basisklasse betrachtet? –

+0

Ja, es ist auch eine Blattklasse –

+0

Es kann eine Basisklasse sein, aber nicht die Basisklasse von B. – Ari

4

sizeof (A) kann nicht 0 sein, weil jeder Teil eines Objekts sein sollte „adressierbar“ (das ist eine andere Adresse haben sollte, wenn wir Operator &)

struct A 
{ 
}; 

struct B 
{ 
    A m_a1; 
    A m_a2; 
}; 

void test() 
{ 
    B b; 
    A* pa1 = &b.m_a1; 
    A* pa2 = &b.m_a2; 

    // "pa1" need to be different from "pa2" 
} 
+0

+1 Das ist richtig. Außerdem sollte jede neue Klasse eine andere Adresse zurückgeben, damit die Verwendung von delete ordnungsgemäß funktioniert. Das ist der Grund, warum Klassen in C++ keine Größe = 0 haben können. Abgesehen davon gibt es Aspekte des Auffüllens, die ein Compiler hinzufügen kann, um das Objekt an der Speicherwortgrenze auszurichten. – Abhay

Verwandte Themen