Одним из предложений будет использование либо шаблонов pimpl, либо абстрактных «интерфейсов».
Шаблон pimpl - это место, где вы храните указатель на объявленный вперед класс реализации.
Пример:
blah.hpp
class foo
{
struct impl;
impl* myImpl;
public:
foo();
}
blah.cpp
#incldue <internalClass>
struct foo::impl
{
internalClass o;
};
foo::foo()
{
myImpl = new impl();
}
Другой вариант - иметь чистый виртуальный абстрактный класс (AKA-интерфейс).
Затем у вас есть фабричная функция (или фабричный класс), возвращающая указатель на вашу реализацию.
Таким образом, клиентский код никогда не должен видеть членов внутри вашей реализации.
Пример:
inter.hpp
class inter
{
virtual void doFoo() = 0;
inter* create();
};
realInter.hpp
class realInter: public inter
{
virtual void doFoo() { //blah blah blah}
internalClass aMember;
};
inter.cpp
#include <realInter.hpp>
inter* inter::create()
{
return new realInter();
}