#новичкам
Сорри за тавталогию, но мимо этой темы мы не можем пройти(хотя я бы прошел, если бы не @shumilkinad, спасибо ему)
В раннем С++ уже были классы и наследование, но в С этого не было. Как же можно транслировать наследование классов в С'шный код?
Простая агрегация и никакого мошенничества.
Все классы в С++ - это простые С-структуры с отдельным набором функций, принимающих cv-специфицированный указатель на инстанс структуры(это мы выяснили в прошлом посте). Наследники же в начале объекта хранят все поля базового класса. Так давайте просто первым полем наследника сделаем инстанс базовой структуры. Таким образом мы обеспечим вложенность объектов с любым количеством наследований.
Вот есть пара родитель-наследник:
class Base {
public:
int x;
Base(int a) : x(a) {}
};
class Derived : public Base {
public:
int y;
int z;
Derived(int a, int b) : Base(a), y(b) {
z = x + y;
}
};Примерно в такой код они транслировались:
struct Base {
int x;
};
struct Derived {
struct Base _base; // embedded base object
int y;
int z;
};
void Base_constructor(struct Base* this, int a) {
this->x = a;
// Constructor body (if presented)
}
void Derived_constructor(struct Derived* this, int a, int b) {
// Init base object
Base_constructor(&this->_base, a);
// Init fields of derived object
this->y = b;
// Constructor body
this->z = this->_base.x + this->y;
}Первым полем структуры Derived - структура Base.
Конструкторы же - это отдельные функции. Но в С++ очень важен порядок вызовов конструкторов и деструкторов.
Поэтому конструктор самого базового класса только инициализирует свои поля и дальше выполняет инструкции из тела конструктора. При создании же наследников в начале вызывается конструктор базового класса и лишь потом инициализация полей и выполнение тела.
Разрушение же объекта выполняется в обратном порядке. Трусы снимаются только после штанов, раньше не получится.
class Base {
public:
~Base() {
// Destructor Base body
}
};
class Derived : public Base {
public:
~Derived() {
// Destructor Derived body
}
}Превращается в:
struct Base {
};
struct Derived {
struct Base _base;
};
void Base_destructor(struct Base* this) {
// Destructor Base body
}
void Derived_destructor(struct Derived* this) {
// Destructors execute in reverse order
// Destructor Derived body
Base_destructor(&this->_base);
}Новичкам особенно будет полезно понимать, как простой код С++ может быть написан на С, чтобы досканально понимать все абстракции языка и какие действия скрыты от наших глаз.
Have a legacy. Stay cool.
#cppcore #goodoldc #compiler