dimanche 5 septembre 2021

C++ Two Classes Template Methods Reference (Not Compose) Each Other

I've gotten into a bit of a design block in a C++ program of mine as two different header files are required to reference each other. Typically a forward declaration would be used here, but since both classes use template functions/constructors a forward declaration cannot be used as methods/variables from both classes need to be used.

For example consider the following scenario (this is pseudo code as an example, it may/may not compile. The objects are representative of my actual application so if a redesign is necessary then I'd love to understand the design philosophies of what I did wrong)

// Application.hpp
#include <Assets.hpp>
#include <Logger.hpp>

class Application {
public:
    
    // Some brilliant code here ...
    Logger myLogger;

    template <int someArrayLen> Application(std::array<int, someArrayLen> myArr, SomeOtherTypes someOtherStuff) : myLogger(stuffHere) {
        mainAssets = new Assets(myArr);
    }

    ~Application(); // Assume this is implemented in Application.cpp and has delete mainAssets;
};

extern Application* mainApp; // Assume Application* mainApp = nullptr; in Application.cpp
// Assets.hpp
// #include <Application.hpp> ???? The issue lies here

class Assets {
private:
    // Random data structures/stuff for holding shaders/textures/etc

protected:
    
    template <int someArrayLen> Assets(std::array<int, someArrayLen> myArr) {
        if (!shadersSupported()) {
            // Main app is an unknown symbol
            mainApp->myLogger->error("Your GPU is too old/whatever!");
        }

        // Random code for loading assets based on my template stuff
    }

    friend class Application;

public:
    // Get assets/whatever here
};

extern Assets* mainAssets; // Assume Assets* mainAssets = nullptr; in Assets.cpp

How can I fix the compile error regarding mainApp being an unknown symbol? Any feedback/help is appreciated, thanks!

I've already looked through all the following questions but none address this unique scenario:

I've also already considered the following:

  • Trying to change from std::array to pointers, this wouldn't work as my Assets constructor does rely on the lengths of the array.
  • Trying to change from std::array to std::vector, I want to stick to aggregate initialization so it can be done at compile time, I believe vectors/lists would be too heavy for this.

Aucun commentaire:

Enregistrer un commentaire