Я думаю, что недавно столкнулся с той же проблемой, что и оригинальный постер, и решил ее следующим образом:
Я пишу оболочку вокруг стороннего API, определенного как:
foo.h:
typedef struct _foo
{
int i;
} Foo;
Foo* MakeFoo();
int UseFoo(Foo* foo);
В моей оболочке должен быть член Foo, но я не хочу показывать Foo всем потребителям моей оболочки.
UberFoo.h:
#pragma once
struct _foo; // forward declare the actual type _foo, not the typedef Foo
class UberFoo
{
public:
UberFoo();
int GetAnswer();
private:
_foo* f;
};
UberFoo.cpp:
#include "UberFoo.h"
#include "Foo.h"
UberFoo::UberFoo()
{
this->f = MakeFoo();
}
int UberFoo::GetAnswer()
{
return UseFoo(f);
}
Теперь потребители моего класса могут создавать его экземпляры, не имея доступа к действительному определению _foo / Foo. Это также сработало бы, если бы мне нужно было передавать указатели на _foo в качестве параметров или возвращать их из функций, а также иметь член _foo.
main.cpp:
#include <cstdio>
#include "UberFoo.h"
int main(int argc, char* argv[])
{
UberFoo u;
printf( "The Answer = %d\n", u.GetAnswer());
return 0;
}
Хитрость заключалась в том, чтобы пересылать объявление фактического типа структуры, а не имени typedef. Обратите внимание, что крайне важно, чтобы структура не была анонимной, как это обычно бывает в старом коде C:
typedef struct // the actual struct type underlying the typedef is anonymous here
{
int i;
} ThisWontWork;
Надеюсь, это поможет!