Wt建议使用前向声明以避免循环依赖。
// Settings.h
#include <Wt/Dbo/Dbo.h>
#include <string>
class User; // Forward declaration of User Wt::Dbo object
class Settings
{
public:
Wt::Dbo::ptr<User> user;
template<class Action>
void persist(Action& a)
{
Wt::Dbo::belongsTo(a, user);
}
};
// User.h
#include <Wt/Dbo/Dbo.h>
#include <string>
#include "Settings.h"
class User
{
public:
Wt::Dbo::weak_ptr<Settings> settings;
template<class Action>
void persist(Action& a)
{
Wt::Dbo::hasOne(a, settings);
}
};
但是,当我在另一个cpp文件中使用此Settings
类时,该程序无法编译:
// test.cpp
#include "Settings.h"
错误:C2079:“虚拟”使用未定义的类“用户”
可能的解决方案(我不喜欢)
一个解决方案应在每个包含User.h
的cpp文件的Settings.h
中包含,即:
// test.cpp
#include "User.h"
#include "Settings.h"
我不喜欢这种解决方案,因为每次我添加User.h
时都要记住要包含Settings.h
。
另一种解决方法是使用非推荐的DBO_EXTERN_TEMPLATES
宏,即
// Settings.h
...
class Settings
{
public:
....
};
DBO_EXTERN_TEMPLATES(Settings)
我不喜欢此解决方案,因为不建议也未记录此宏。 DBO_EXTERN_TEMPLATES
不适用于所有编译器。
问题
a。克服Wt::Dbo
对象之间的循环依赖关系以避免上述undefined class
错误的最佳/首选方法是什么?
b。 为什么解决方案1.起作用?
我创建了一个新的(一般的-不是Wt::Dbo
特定问题)(使用MCVE),以阐明具体情况:When are member functions of a templated class instantiated?
参考
Wt::Dbo
教程:https://www.webtoolkit.eu/wt/doc/tutorial/dbo.html#_em_one_to_one_em_relations,但我想将不同的类放入不同的头文件中。我不熟悉Wt::Dbo
,但我不认为这个问题是特定的。这是一个更常见的C ++类设计问题,您需要解决/解决;实际上,这在C ++项目中相当普遍。
基于ChrisMM的答案,另一种解决方案是在其头文件的顶部转发声明您的类: