Chciałbym dokładnie wiedzieć, w jaki sposób zajęcia będą układane w pamięci esp. z dziedziczeniem i funkcjami wirtualnymi.układ pamięci odziedziczonej klasy
Wiem, że nie jest to zdefiniowane przez standard języka C++. Czy istnieje jednak prosty sposób, aby dowiedzieć się, w jaki sposób twój konkretny kompilator wdroży te słowa, pisząc jakiś kod testowy?
EDIT: - Korzystanie niektóre z poniższych odpowiedzi: -
#include <iostream>
using namespace std;
class A {
public:
int a;
virtual void func() {}
};
class B : public A {
public:
int b;
virtual void func() {}
};
class C {
public:
int c;
virtual void func() {}
};
class D : public A, public C {
public:
int d;
virtual void func() {}
};
class E : public C, public A {
public:
int e;
virtual void func() {}
};
class F : public A {
public:
int f;
virtual void func() {}
};
class G : public B, public F {
public:
int g;
virtual void func() {}
};
int main() {
A a; B b; C c; D d; E e; F f; G g;
cout<<"A: "<<(size_t)&a.a-(size_t)&a<<"\n";
cout<<"B: "<<(size_t)&b.a-(size_t)&b<<" "<<(size_t)&b.b-(size_t)&b<<"\n";
cout<<"C: "<<(size_t)&c.c-(size_t)&c<<"\n";
cout<<"D: "<<(size_t)&d.a-(size_t)&d<<" "<<(size_t)&d.c-(size_t)&d<<" "<<(size_t)&d.d- (size_t)&d<<"\n";
cout<<"E: "<<(size_t)&e.a-(size_t)&e<<" "<<(size_t)&e.c-(size_t)&e<<" "<<(size_t)&e.e- (size_t)&e<<"\n";
cout<<"F: "<<(size_t)&f.a-(size_t)&f<<" "<<(size_t)&f.f-(size_t)&f<<"\n";
cout<<"G: "<<(size_t)&g.B::a-(size_t)&g<<" "<<(size_t)&g.F::a-(size_t)&g<<" " <<(size_t)&g.b-(size_t)&g<<" "<<(size_t)&g.f-(size_t)&g<<" "<<(size_t)&g.g-(size_t)&g<<"\n";
}
a wyjście jest: -
A: 8
B: 8 12
C: 8
D: 8 24 28
E: 24 8 28
F: 8 12
G: 8 24 12 28 32
Więc wszystkie klasy posiadają V-ptr w Loc 0 wielkości 8 D ma inny v-ptr w miejscu 16. Podobnie jak w przypadku E. G wydaje się mieć również v-ptr w wieku 16 lat, chociaż z mojego (ograniczonego) zrozumienia domyśliłbym się, że ma więcej.
+1 Ten przykładowy kod jest najbliższy temu, co wymyśliłem. Po prostu staraj się unikać polegania na układzie pamięci. Nie ma gwarancji, że pozostanie taki sam w przyszłych wersjach kompilatora (lub nawet w innych kontekstach z tą samą wersją kompilatora, np. Optymalizacją). Założę się, że prawie zawsze istnieje lepszy sposób na rozwiązanie problemu. – Andre
Dzięki. To trochę pomaga. Łącząc twoją odpowiedź z Azzą ... Byłem również zainteresowany tym, co by się stało, gdybyśmy mieli klasę A: ; klasa B; klasa C: publiczna A, publiczna B; Wydaje się, że daje to wynik, gdy istnieje wiele wskazówek do vtable. Członkowie danych A wydają się być pierwsi przed B. – owagh
Nigdy nie zajmowałem się dziedziczeniem wielokrotnym. Ale nadal możesz spróbować zobaczyć, co pokazują przesunięcia. Naprawdę nie mam pojęcia, jak wiele dziedziczenia działa pod spodem. – Mysticial