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 解决了这个独特的场景:
- two classes referencing each other
- 这个问题没有使用模板,因此可以使用前向声明,因为 headers
中没有定义方法体
- 这个问题的解决方案不能使用,因为这里编译器无法计算出要分配多少内存,而在我的问题中,问题不在于编译器混淆了分配多少,而是什么供参考
- Two template classes being composed of a member of each other
- 这个问题解决了我的应用程序没有的循环依赖的设计缺陷,两个 classes 都是全局存储的,它们只是在相互引用的单独构造函数中实例化。
- Two classes that refer to each other
- 这个问题提供了前向声明作为解决方案,由于需要在模板函数定义中使用 class methods/constructors,所以不能在这里使用。
我也已经考虑过以下内容:
- 尝试从 std::array 更改为指针,这行不通,因为我的资产构造函数确实依赖于数组的长度。
- 尝试从 std::array 更改为 std::vector,我想坚持聚合初始化以便可以在编译时完成,我相信 vectors/lists 对这个来说太重了.
前向声明确实可以解决您的问题。关键是函数模板可以不在行中定义(即不在您的 class ... { };
声明中)legally. The same can be achieved for arbitrary functions using the inline
keyword.
现在要解决您的具体问题,只需将 Application.hpp
拆分为 Applicaton_fwd.hpp
和 Application.hpp
- 类似于 iosfwd
。 Application_fwd.hpp
包含几乎所有代码,Application.hpp
在定义 Application::Application
函数模板之前包含 Application_fwd.hpp
和 Assets.hpp
(就像您在 *.cpp
文件).
在Assets.hpp
中只要不使用构造函数就可以直接使用Application_fwd.hpp
。如果您还在 Assets.hpp
中使用 Application
构造函数,事情会变得有点复杂,因为您需要非常仔细地考虑所有可能的包含场景(即,每次您的 headers 由他们自己或用户包含)以确保它按照您需要的顺序解析,而不会引起守卫的麻烦。
你可以看到它的实际效果here
我在我的 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 解决了这个独特的场景:
- two classes referencing each other
- 这个问题没有使用模板,因此可以使用前向声明,因为 headers 中没有定义方法体
- 这个问题的解决方案不能使用,因为这里编译器无法计算出要分配多少内存,而在我的问题中,问题不在于编译器混淆了分配多少,而是什么供参考
- Two template classes being composed of a member of each other
- 这个问题解决了我的应用程序没有的循环依赖的设计缺陷,两个 classes 都是全局存储的,它们只是在相互引用的单独构造函数中实例化。
- Two classes that refer to each other
- 这个问题提供了前向声明作为解决方案,由于需要在模板函数定义中使用 class methods/constructors,所以不能在这里使用。
我也已经考虑过以下内容:
- 尝试从 std::array 更改为指针,这行不通,因为我的资产构造函数确实依赖于数组的长度。
- 尝试从 std::array 更改为 std::vector,我想坚持聚合初始化以便可以在编译时完成,我相信 vectors/lists 对这个来说太重了.
前向声明确实可以解决您的问题。关键是函数模板可以不在行中定义(即不在您的 class ... { };
声明中)legally. The same can be achieved for arbitrary functions using the inline
keyword.
现在要解决您的具体问题,只需将 Application.hpp
拆分为 Applicaton_fwd.hpp
和 Application.hpp
- 类似于 iosfwd
。 Application_fwd.hpp
包含几乎所有代码,Application.hpp
在定义 Application::Application
函数模板之前包含 Application_fwd.hpp
和 Assets.hpp
(就像您在 *.cpp
文件).
在Assets.hpp
中只要不使用构造函数就可以直接使用Application_fwd.hpp
。如果您还在 Assets.hpp
中使用 Application
构造函数,事情会变得有点复杂,因为您需要非常仔细地考虑所有可能的包含场景(即,每次您的 headers 由他们自己或用户包含)以确保它按照您需要的顺序解析,而不会引起守卫的麻烦。
你可以看到它的实际效果here