Zawijam prostą hierarchię dziedziczenia C++ do "obiektowo zorientowanego" C. Próbuję ustalić, czy istnieją jakieś błędy w traktowaniu wskaźników do obiektów C++ jako wskaźników nieprzejrzystych C structs. W szczególności, w jakich okolicznościach konwersja wyprowadzona z bazy powodowałaby problemy?Zawijanie C++ w C: pochodne do bazowych konwersji
Klasy sami są stosunkowo skomplikowane, ale hierarchia jest płytkie i wykorzystuje tylko jeden-dziedziczenia:
// 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..
Ja planuje na wystawienie tego klientom C poprzez następujący, dość standardowe obiektowego 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;
}
Klienty C przekazują tylko wskaźniki do obiektów C++ i mogą nimi manipulować tylko za pomocą wywołań funkcji. Tak więc klient może w końcu zrobić coś takiego:
first_derived_t* object = first_derived_create();
base_some_operation((base_t*) object); // Note the derived-to-base cast here
...
i mieć wirtualny wezwanie do FirstDerived :: someOperation() sukcesu, jak oczekiwano.
Te klasy nie są standard-layout, ale nie korzystają z dziedziczenia wielokrotnego lub wirtualnego. Czy to gwarantuje działanie?
Należy pamiętać, że mam kontrolę nad całym kodem (C++ i C wrapper), jeśli to ma znaczenie.
Po prostu używaj 'void *' wszędzie jako nieprzezroczystego typu. –