Второй вариант заставляет вас писать очень длинные имена, такие как myobj.parent.grandparent.attribute
, что ужасно. Первый вариант лучше с синтаксической точки зрения, но приводить дочерние элементы к родительским немного рискованно - я не уверен, гарантируется ли стандартом, что разные структуры будут иметь одинаковые смещения для одинаковых элементов. Я думаю, компилятор может использовать разные отступы для таких структур.
Существует еще один вариант, если вы используете GCC - анонимные члены структуры, которые являются частью расширения MS, поэтому я предполагаю, что он был создан неким компилятором MS и все еще может поддерживаться MS.
Объявления выглядят как
struct shape {
double (*area)(struct shape *);
const char *name;
};
struct square {
struct shape; // anonymous member - MS extension
double side;
};
struct circle {
struct shape; // anonymous member - MS extension
double radius;
};
В вашей функции "конструктор" вам нужно указать правильную функцию для вычисления площади и наследования и полиморфизма. Единственная проблема, которую вам всегда нужно передать явно this
- вы не можете просто позвонить shape[i]->area()
.
shape[0] = (struct shape *)new_square(5);
shape[1] = (struct shape *)new_circle(5);
shape[2] = (struct shape *)new_square(3);
shape[3] = (struct shape *)new_circle(3);
for (i = 0; i < 4; i++)
printf("Shape %d (%s), area %f\n", i, shape[i]->name,
shape[i]->area(shape[i])); // have to pass explicit 'this'
Компилировать с gcc -fms-extensions
.
Я никогда не использовал его в реальных проектах, но я протестировал его некоторое время назад, и это сработало.