Вы смешиваете идиому C (встроенные структуры) с концепциями C ++ (виртуальные функции).В C ++ необходимость встроенных структур устраняется за счет классов и наследования.virtual
функции влияют только на классы в одной иерархии наследования.В вашем случае нет никакой связи между A
и B
, поэтому A
s doStuff
всегда будет вызываться.
Ваша ошибка, вероятно, вызвана тем, что b
являетсядействительно B
, но присваивается A*
.Когда компилятор видит b->doStuff
, он пытается перейти к vtable, чтобы посмотреть, какую версию doStuff
вызвать.Однако B
не имеет vtable, поэтому ваша программа аварийно завершает работу.
В C ++ класс без виртуальных функций, который не наследуется от каких-либо других классов, выложен в точности как структура C.
class NormalClass
{
int a;
double b;
public:
NormalClass(int x, double y);
};
выглядит следующим образом:
+------------------------------------+
| a (4 bytes) | b (8 bytes) |
+------------------------------------+
Однако класс (или структура) с виртуальными функциями также имеет указатель на vtable, что позволяет использовать версию полиморфизма C ++.Таким образом, такой класс:
class ClassWithVTable
{
int a;
double b;
public:
ClassWithVTable();
virtual void doSomething();
};
размещается в памяти следующим образом:
+-----------------------------------------------------------+
| vptr (sizeof(void *)) | a (4 bytes) | b (8 bytes) |
+-----------------------------------------------------------+
и vptr
указывают на таблицу, определяемую реализацией, которая называется vtable
,по сути, это массив указателей на функции.