sizeof-Klasse mit int-Funktion, virtual-Funktion in C++?
Dies ist ein online-C++ - test-Frage, was getan wird.
#include<iostream>
using namespace std;
class A
{
};
class B
{
int i;
};
class C
{
void foo();
};
class D
{
virtual void foo();
};
class E
{
int i ;
virtual void foo();
};
class F
{
int i;
void foo();
};
class G
{
void foo();
int i;
void foo1();
};
class H
{
int i ;
virtual void foo();
virtual void foo1();
};
int main()
{
cout <<"sizeof(class A) : " << sizeof(A) << endl ;
cout <<"sizeof(class B) adding the member int i : " << sizeof(B) << endl ;
cout <<"sizeof(class C) adding the member void foo() : " << sizeof(C) << endl ;
cout <<"sizeof(class D) after making foo virtual : " << sizeof(D) << endl ;
cout <<"sizeof(class E) after adding foo virtual , int : " << sizeof(E) << endl ;
cout <<"sizeof(class F) after adding foo , int : " << sizeof(F) << endl ;
cout <<"sizeof(class G) after adding foo , int : " << sizeof(G) << endl ;
G g;
cout <<"sizeof(class G) after adding foo , int : " << sizeof(g) << endl ;
cout <<"sizeof(class H) after adding int 2 virtual " << sizeof(H) << endl ;
return 0;
}
Ausgabe:
sizeof(class A) : 1
sizeof(class B) adding the member int i : 4
sizeof(class C) adding the member void foo() : 1
sizeof(class D) after making foo virtual : 8
sizeof(class E) after adding foo virtual , int : 16
sizeof(class F) after adding foo , int : 4
sizeof(class G) after adding foo , unsigned int : 4
sizeof(class g) after adding foo , unsigned int : 4
sizeof(class H) after adding int 2 virtual 16
Meine Fragen:
Warum siszeof(A)
1 und sizeof(C)
1 zu ?
Warum siszeof(H)
ist 16 aber sizeof(G)
4 ?
Warum siszeof(E)
ist 16 aber sizeof(F)
4 ?
Warum siszeof(D)
ist 8 aber sizeof(E)
ist 16 ?
Meine Vermutung:
Einer virtuellen Funktion ist ein Zeiger 8 bytes.
Aber, ich weiß nicht, warum E
Größe 16 ?
Hinzufügen einer Funktion zu einer leeren Klasse ändert nicht seine Größe ?
Jede Hilfe ist willkommen.
Dank
Der compiler ist frei, zu richten die Mitglieder, wie es gerade passt.
Dieser fühlt sich viel wie eine Hausaufgaben-Frage. Ist es?
Vor ein paar Monaten, die Sie geschrieben, eine Lawine von kopieren-einfügen interview-Fragen und zeigte kein Interesse an der eigentlich nach oben, oder der Bevölkerungsgruppe, oder nehmen Sie sich etwas Zeit und denken und lernen für sich selbst. Jetzt bist du wieder genau das gleiche wieder. Dies ist nicht ein tutorial-website, und Sie haben zu tun, einige nach unten und schmutzig das lernen selbst. Darüber hinaus suchen diese Website vor der Buchung, wie viele von den Themen, die Sie (wird) bringen die diskutiert wurden, über und über auf ALSO schon.
Dieser fühlt sich viel wie eine Hausaufgaben-Frage. Ist es?
Vor ein paar Monaten, die Sie geschrieben, eine Lawine von kopieren-einfügen interview-Fragen und zeigte kein Interesse an der eigentlich nach oben, oder der Bevölkerungsgruppe, oder nehmen Sie sich etwas Zeit und denken und lernen für sich selbst. Jetzt bist du wieder genau das gleiche wieder. Dies ist nicht ein tutorial-website, und Sie haben zu tun, einige nach unten und schmutzig das lernen selbst. Darüber hinaus suchen diese Website vor der Buchung, wie viele von den Themen, die Sie (wird) bringen die diskutiert wurden, über und über auf ALSO schon.
InformationsquelleAutor user1002288 | 2012-02-24
Du musst angemeldet sein, um einen Kommentar abzugeben.
First off, ist eine virtuelle Funktion nicht ein Zeiger 8 bytes. In C++ nichts, aber
sizeof(char)
wird garantiert, um eine beliebige Anzahl von bytes.Zweiten, nur die erste virtuelle Funktion in einer Klasse erhöht seine Größe (compiler-abhängig, aber auf die meisten - wenn nicht alle - es ist wie dieses). Alle nachfolgenden Methoden nicht. Nicht-virtuelle Funktionen wirken nicht auf die Klasse angepasst.
Dies geschieht, weil eine Instanz der Klasse nicht zu halten Zeiger auf Methoden selbst, sondern zu einem virtual function table, die eine pro-Klasse.
Also, wenn Sie hatte:
und
hätten Sie
sizeof(A) == sizeof(B)
.Und jetzt:
A
undC
haben Größe 1, nur weil es nicht zulässig, für eine Klasse zu der Größe 0. Die Funktionen haben damit nichts zu tun. Es ist nur ein dummy-byte.G
hat nur ein Mitglied, dass die Konten für den Speicher - dieint
. Und auf Ihre Plattformsizeof(int) == 4
.H
neben derint
hat, hat auch einen Zeiger auf dievftable
(virtual function table, siehe oben). Die Größe dieser, die Größe von int und Justage sind compiler-spezifisch.Oben erklärt - nicht-virtuelle Methoden nicht belegen Speicher in der Klasse.
D
enthält nur dievftable
Zeiger, die offenbar 8 bytes auf Ihrer Plattform.E
hat auch ein int, und dievftable
ausgerichtet ist 8 bytes. Es ist also so etwas wie:sizeof(uint8_t) == 1
(es gibt keine andere Möglichkeit),sizeof(char[100]) == 100
usw.Die Polsterung sollte wohl auch erwähnt.
was
sizeof char[53]
?erwähnt. (jetzt)
dass nicht kompilieren, da braucht es Klammern, aber
sizeof(char[53])
garantiert werden 53.InformationsquelleAutor Luchian Grigore
Die Funktion in
C
ist nicht virtuell, so dass die Klasse nicht brauchen einen vtable-Zeiger, also es braucht nicht mehr Speicher alsA
. WederA
nochC
brauchen keine Speicher, sondern weil die Sprache erfordert, dass verschiedene Instanzen der gleichen Klasse haben unterschiedliche Zeiger, können Sie nicht haben eine Größe von null - also der compiler macht Sie so klein, wie es kann, also 1 byte.G
hat keine virtuellen Funktionen, so dass alle es speichern muss, ist die int, die auf Ihrem compiler und Architektur ist 4 bytes.H
hat virtuelle Funktionen, so muss die Klasse enthaltenint
und einen vtable-Zeiger. Alle verbreiteten Compiler speichern die vtable-Zeiger an den Anfang der Klasse, also das layout {vptr, int}, was ist 8+4=12 Byte, wenn Sie auf einem 64 bit host.Aber der compiler ist frei, um dieses pad aus 16 bytes, so dass, wenn mehrere Instanzen von
H
zugeordnet sind, in ein array, dann werden alle von Ihnen "word" ausgerichtet sein. Dies ist wichtig, weil es erhebliche Auswirkungen auf die Leistung für den Zugriff auf einen Zeiger (d.h. die vtable-Zeiger hier), wenn es nicht am "word" ausgerichtet.E hat virtuelle Funktionen, so muss eine vtable ptr, so das layout ist genau wie
H
's.F
hat keine virtuellen Funktionen, es hat nur einen int, also das layout ist genau wieG
's. also die Antwort ist die gleiche wie fürG
undH
.Die Reihenfolge der Elemente/Funktionen spielt einfach keine Rolle hier, denn es gibt nur eine member-variable und die vtable ptr geht immer zuerst, wenn es einen gibt.
D
hat keine member-Variablen, aber es ist eine virtuelle Funktion, so braucht es ein vtable-Zeiger. Der vtable-Zeiger ist die einzige Sache, die es braucht, damit seine Größe istsizeof(void*)
von 8 bytes.E
muss die gleiche wieD
, plus 4 bytes für einen integer, und der compiler rundet es bis zu 16 bytes für die Ausrichtung.InformationsquelleAutor je4d
Es ist so, weil der C++ standard, die verbietet, Klassen/structs der Größe 0. Das ist, warum Sie eine leere struct/Klasse haben die Größe 1.
Ich finde es ziemlich nervig, aber Sie hatten einige Gründe für, die.
Das ist die Größe von int, schlicht und einfach 🙂
Das ist die Größe einer leeren Struktur (siehe A). Nicht virtuelle Funktionen nicht dazu beitragen, die Größe des Objekts auf alle. Es gibt nichts, was Sie speichern müssen, die in einem Objekt aufrufen zu können, seine nicht virtuelle member-Funktion.
Ich gehe davon aus, dass Sie eine 64-bit-Anwendung. Jede Klasse, die mindestens 1 virtuelle Funktion hat einen Zeiger auf eine Tabelle virtueller Methoden. Diese können Sie aufrufen, eine richtige virtuelle Funktion, auch wenn ein Zeiger auf ein Objekt geformt war, um einige übergeordnete Klasse. Oft wird der Zeiger bezeichnet als vtable. Mehr zu Lesen bei wiki: http://en.wikipedia.org/wiki/Virtual_method_table
Ich denke die Größe 8 ist aus, die 64-bit-Zeiger.
Speichern einen Zeiger und ein int, die Sie technisch braucht 12 bytes. Jedoch, ein Zeiger ausgerichtet werden muss, um 8 bytes. Jetzt stellen Sie sich selbst erstellen Sie ein array A von Objekten E.
A[0].vtable
hätte-Adresse &A+0,A[0].i
wäre bei&A+8
,A[1].vtable
wäre bei&A+12
-- woops, wir haben ein problem, 12 ist nicht divisable von 8. Das ist, warum der compiler erstellt eine Polsterung. Es fügt zusätzliche nutzlose Byte, um das Objekt korrekt ausgerichtet in einem array. In diesem Fall, der niedrigste divisable von 8 Anzahl ist 16. Daher ist die Größe.Gleiche wie bei C - nicht virtuelle Funktionen nicht tragen überhaupt zu der Größe, so dass Ihre Größe entspricht B.
sizeof(G)==4 -- gleich wie F
sizeof(H)==16
Die Anzahl der virtuellen Funktionen, spielt keine Rolle. Es ist nur noch ein vtable-Zeiger in das Objekt. Wenn Sie mehr virtuelle Funktionen, virtuelle Tabelle wird größer, aber nicht das Objekt selbst. In vielen Objekt-orientierten Programme, die Sie Häufig am Ende mit vielen virtuellen Funktionen. Mit Zeiger gespeichert und direkt in das Objekt selbst wäre eine Verschwendung.
Deshalb ist die Größe (und die Erklärung) von H entspricht der Größe von E.
Alles ist auf seiner Plattform. Das ist zwar nicht standard, in den meisten modernen Compilern
int
ist ein 32-bit-Ganzzahl, die die Einnahme von 4 bytes. Dasselbe gilt für leere Strukturen der Einnahme von 1 byte, etc... ich denke, in der Antwort auf diese Frage ist es unnötig zu wohnen-Plattform in Vielfalt und compiler-Implementierung Besonderheiten.Im Gegenteil. Für einen Anfänger ist es sehr wichtig, zu verstehen, was ist und ist nicht an eine bestimmte Plattform gebunden.
... aber Anfänger wird wahrscheinlich nicht funktionieren auf einem system, das nicht-32-bit-Ganzzahlen in irgendeiner vorhersehbaren Zukunft. Und wenn er das tut, wird er viel besser erzogen, um zu wissen, was ist und was ist nicht an eine bestimmte Plattform gebunden.
Ich verstehe nicht, warum Leute würden argumentieren, dass es okay ist, etwas zu sagen, das ist eindeutig falsch, nur weil es sehr verbreitet ist, oder die person, die nicht braucht, um zu wissen, die details in dieser Phase, statt nur die Bearbeitung der Antwort, um es zu korrigieren.
InformationsquelleAutor CygnusX1
Größe von int mit Polsterung und die virtuelle Funktion =18 bytes
einfache Funktion bytes =1
virtuelle Funktion =8
Und Sie cant fügen Sie einfach alle bytes, die es ist Konzept der Polsterung check it out auf google.
Erklärte in unterschiedlicher Reihenfolge ändern Sie die Größe der Klasse
InformationsquelleAutor