C++ 两个 类 模板方法相互引用(不是组合)

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

我在我的 C++ 程序中遇到了一些设计障碍,因为需要两个不同的 header 文件来相互引用。通常这里会使用前向声明,但由于两个 classes 都使用模板 functions/constructors 不能使用前向声明,因为需要使用两个 classes 的 methods/variables。

例如考虑以下场景(这是伪代码作为示例,它 may/may 无法编译。objects 代表我的实际应用程序,所以如果需要重新设计,那么我'我喜欢了解我做错了什么的设计哲学)

// 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

如何修复有关 mainApp 是未知符号的编译错误?任何 feedback/help 不胜感激,谢谢!

我已经查看了以下所有问题,但 none 解决了这个独特的场景:

我也已经考虑过以下内容:

前向声明确实可以解决您的问题。关键是函数模板可以不在行中定义(即不在您的 class ... { }; 声明中)legally. The same can be achieved for arbitrary functions using the inline keyword.

现在要解决您的具体问题,只需将 Application.hpp 拆分为 Applicaton_fwd.hppApplication.hpp - 类似于 iosfwdApplication_fwd.hpp 包含几乎所有代码,Application.hpp 在定义 Application::Application 函数模板之前包含 Application_fwd.hppAssets.hpp(就像您在 *.cpp 文件).

Assets.hpp中只要不使用构造函数就可以直接使用Application_fwd.hpp。如果您还在 Assets.hpp 中使用 Application 构造函数,事情会变得有点复杂,因为您需要非常仔细地考虑所有可能的包含场景(即,每次您的 headers 由他们自己或用户包含)以确保它按照您需要的顺序解析,而不会引起守卫的麻烦。

你可以看到它的实际效果here