I have created a C++ module which has an API part and an internal part. The API contains a long (more then 30) list of polymorphic classes inheriting directly or indirectly from the same baseclass. In my internal classes/functions these classes are used differently, so I moved some functionality to these classes to be used polimorphically. These functionalites depend on some internal resources, while the internal functions depend on these classes so I broke this circular dependency by forward declaring the necessary classes in the .h files and including them in the .cpp files. This way my module compiles and works perfectly.
Here comes the problem. When I include the API from another module, I get "undefined reference to ...." errors to internal functions in the API classes polimorphic functions. I think this is due to the forward declarations. These internal classes are never defined in the eyes of the second module which uses the API.
Broadly my module looks like this:
InternalClass.h:
class ApiObjBase;
class InternalClass {
public:
  static InternalClass& get(); // singleton
  void processApiObjBase(ApiObjBase& apiObj);
  static const Resource& getResource1();
  static const Resource& getResource2();
  static const std::map<uint64_t, std::unique_ptr<ApiObjBase>>& getApiObjStorage();
  UacManager(const UacManager&) = delete; // singleton
  UacManager& operator=(const UacManager&) = delete; // singleton
private:
  InternalClass(); // singleton
  Resource resource1;
  Resource resource2;
  std::map<uint64_t, std::unique_ptr<ApiObjBase>> ApiObjStorage;
}
InternalClass.cpp:
#include "ApiObjBase.h"
void InternalClass::processApiObjBase(ApiObjBase& apiObj) {
  apiObj.internalPolyFunc1();
  apiObj.internalPolyFunc2();
  // ...
}
const Resource& InternalClass::getResource1() {
  return get().resource1;
}
const Resource& InternalClass::getResource2() {
  return get().resource2;
}
// Other implementations of member functions ...
ApiObjBase.h:
class InternalClass;
class ApiObjBase {
protected:
  int internalVariable1;
  int internalVariable2;
  
  int apiVariable1;
  int apiVariable2;
public:
  ApiObjBase() = default;
  // getters, setters
  void internalPolyFunc1() = 0;
  void internalPolyFunc2() = 0;
  void apiPolyFunc1() = 0;
  void apiPolyFunc2() = 0;
}
ApiObjBase.cpp:
#include "ApiObjBase.h"
// ...
ApiObjDerived1.h:
#include "ApiObjBase.h"
class ApiObjDerived1 : public ApiObjBase {
protected:
  int internalVariable3;
  int internalVariable4;
  
  int apiVariable3;
  int apiVariable4;
public:
  ApiObjDerived1() = default;
  // getters, setters
  void internalPolyFunc1() override;
  void internalPolyFunc2() override;
  void apiPolyFunc1() override;
  void apiPolyFunc2() override;
}
ApiObjDerived1.cpp:
#include "ApiObjDerived1.h"
#include "InternalClass.h"
void ApiObjDerived1::internalPolyFunc1() {
  Resource& res = InternalClass::getResource1(); // 
  // ...
}
void ApiObjDerived1::internalPolyFunc2() {
  Resource& res = InternalClass::getResource1();
  // ...
}
void ApiObjDerived1::apiPolyFunc1() {
  // ...
}
void ApiObjDerived1::apiPolyFunc2() {
  // ...
}
// ...
ApiObjDerived2.h:
#include "ApiObjBase.h"
class ApiObjDerived2 : public ApiObjBase {
protected:
  int internalVariable5;
  int internalVariable6;
  
  int apiVariable5;
  int apiVariable6;
public:
  ApiObjDerived2() = default;
  // getters, setters
  void internalPolyFunc1() override;
  void internalPolyFunc2() override;
  void apiPolyFunc1() override;
  void apiPolyFunc2() override;
}
ApiObjDerived2.cpp:
#include "ApiObjDerived2.h"
#include "InternalClass.h"
void ApiObjDerived2::internalPolyFunc1() {
  Resource& res = InternalClass::getResource2();
  // ...
}
void ApiObjDerived2::internalPolyFunc2() {
  // ...
}
void ApiObjDerived2::apiPolyFunc1() {
  // ...
}
void ApiObjDerived2::apiPolyFunc2() {
  // ...
}
// ...
SomeOtherModule.cpp:
#include "ApiObjDerived2.h"
void main(int argc, char** argv) {
  std::unique_ptr<ApiObjBase> apiObj = std::make_unique<ApiObjDerived2>();
  apiObj.get()->apiPolyFunc1();
  return EXIT_SUCCESS;
}
For this example the error would the following while linking SomeOtherModule:
(...) In function `ApiObjDerived2::internalPolyFunc1()': 
(...) undefined reference to `InternalClass::getResource2()'
My only idea to this problem is to create wrapper classes (ApiObjBaseWrapper, ApiObjDerived1Wrapper, ApiObjDerived2Wrapper) for each polymorphic class and move all internal member variables and functions to them. These wrapper classes would contain the original derived class as a private member variable, which could be accessed by a virtual getter which returns a reference or a pointer to ApiObjBase. This would separate the internal and API part of the module making predeclarations unnecessary in the API, while maintaining all the advantages of polymorphism. After this, InternalClass could use ApiObjBaseWrapper, and SomeOtherModule could continue to use ApiObjBase.
My problem with this idea is that this would require a LOT of new files, classes and code (I would have to create another ~30 classes with .cpp and .h files). I cannot emphasize more how big this module is.
What do you suggest, what should I do?
