Я оборачиваю простую иерархию наследования C++ в «объектно-ориентированный» C. Я пытаюсь выяснить, есть ли какие-либо ошибки в обработке указателей на объекты C++ как указатели на непрозрачные структуры C. В частности, при каких обстоятельствах преобразование производных данных в базовые вызовет проблемы?
Сами классы относительно сложны, но иерархия поверхностна и использует только одиночное наследование:
// A base class with lots of important shared functionality
class Base {
public:
virtual void someOperation();
// More operations...
private:
// Data...
};
// One of several derived classes
class FirstDerived: public Base {
public:
virtual void someOperation();
// More operations...
private:
// More data...
};
// More derived classes of Base..
Я планирую показать это C-клиентам через следующий довольно стандартный объектно-ориентированный C:
// An opaque pointers to the types
typedef struct base_t base_t;
typedef struct first_derived_t first_derived_t;
void base_some_operation(base_t* object) {
Base* base = (Base*) object;
base->someOperation();
}
first_derived_t* first_derived_create() {
return (first_derived_t*) new FirstDerived();
}
void first_derived_destroy(first_derived_t* object) {
FirstDerived* firstDerived = (FirstDerived*) object;
delete firstDerived;
}
Клиенты C передают только указатели на базовые объекты C++ и могут манипулировать ими только через вызовы функций. Таким образом, клиент может, наконец, сделать что-то вроде:
first_derived_t* object = first_derived_create();
base_some_operation((base_t*) object); // Note the derived-to-base cast here
...
и виртуальный вызов FirstDerived::someOperation() преуспевает, как и ожидалось.
Эти классы не являются стандартным макетом но не используйте множественное или виртуальное наследование. Это гарантированно работает?
Обратите внимание, что я контролирую весь код (C++ и C-оболочку), если это имеет значение.