Wie wird der Speicher bei C++ Klassen Instanzen verteilt?
-
nur ne kurze Frage, nichts kompliziertes man muss es einfach wissen, und ich weiss es nicht:
1.wenn ich eine Klasse in c++ deklariere, was passiert da genau? meine Vermutung ist, daß beim deklarieren der Klasse logischerweise erstmal nur der klassen-"prototyp" in den speicher kommt. Und jetzt komtm aber das wichtige um das es mir geht:
wenn ich nun mehrere instanzen dieser Klasse im Hauptprogramm intialisiere, wird dann
a)jeweils für den gesamten Inhalt der Klasse neue Speicher reserviert also auch die Funktionen komplett neu kopiert?
b)oder kriegt die Instanz nur für seine Variablen Speicher reserviert und die Funktionen werden durch pointer zu den Funktionen im prototyp ersetzt?So weit ich das beurtielen kann hätten sowohl a als auch b seine Vorteile, in a) bräuchte man zwar mehr speicher, aber dafür könnte jede Funktion direkt aufgerufen werden, wogegen man in b) immer über den pointer erstmal die adresse der funktion aus dem prototypen bekommen muss.
Irgendjemand ne Ahnung, wie die c++ compiler das machen?
in ähnlicher Form taucht das Problem auch bei abgeleiteten Klassen auf. Werden da in der abgeleiteten Klasse auch nur referenzen auf die funktionen der Basisklasse gepeichert, oder eiun komplett neuer prototyp in den Speicher gebracht?
-
also bei den instanzen werden nur die reinen daten, also variablen etc. angelegt, keine funktionen (und afaik auch keine pointer etc.).
-
die klassendefinition selber verbraucht null speicher. im ram liegen später nur die reinen nutzdaten. das programm braucht sich nicht zur laufzeit die adressen von funktionen merken, die funktionsaufrufe werden doch bereits zur compilierzeit an die richtigen funktionsadressen gebunden.
auch bei basisklassen ändert sich nix. es werden nur die reinen nutzdaten gespeichert. funktionsaufrufe werden weiterhin zur compilezeit an die richtigen funktionsadressen gebunden.
aber wenn man das schlüsselwort "virtual" verwendet, ändert sich die welt. dann wird für die klasse, die ne virtuelle funktion gekriegt hat, eine vtbl gebaut. eine tabelle von funktionzeigern auf die virtuellen funktionen der klasse. und jedes objekt der klasse bekommt einen zeiger auf die vtbl. jedes objekt hat also auf einmal außer den reinen nutzdaten einen zeiger (normalerweise 4 bytes mehr. zur compilezeit kann der compiler nur den index in die vtbl erzeugen. das vervolgen des objekteigenen vtbl-zeigers und je nach index hinspringen in die richhtige funktion muß zur laufzeit geschehen, weil erst dann genau bekannt ist, welchen typ das objekt hat, das in dem basisklassenzeiger steckt.
-
Am einfachsten finde ich immer ein Vergleich mit C:
class A{ int a; char b; public: void do_stuff(char*); }: void A::do_stuff(char*a) { b=*a; }
ist in C:
typedef struct{ int a; char b }A; void A__do_stuff(A*this,char*a) { this->b=*a; }
Wenn du auch noch wissen willst wie Vererbung geht dann post nur.