Wt recommends to use forward declarations to avoid circular dependencies.
// 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);
}
};
However, when I use this Settings class in another cpp file, the program doesn't compile:
// test.cpp
#include "Settings.h"
error: C2079: 'dummy' uses undefined class 'User'
Possible solutions (which I do not like)
A solution is to include in
User.hin every cpp file that includesSettings.h, i.e.:// test.cpp #include "User.h" #include "Settings.h"I do not prefer this solution, because I have to remember to include
User.hevery time I includeSettings.h.Another solution is to use the non-recommended
DBO_EXTERN_TEMPLATESmacro, i.e.// Settings.h ... class Settings { public: .... }; DBO_EXTERN_TEMPLATES(Settings)I do not prefer this solution as this macro is not recommend, nor documented.
DBO_EXTERN_TEMPLATESdoesn't work with all compilers.
Question
a. What is the best/preferred methodology to overcome circular dependencies between Wt::Dbo objects avoiding the mentioned undefined class error?
b. Why does solution 1. works?
I created a new (general - not Wt::Dbo specific) question (with an MCVE), to clarify the specific situation: When are member functions of a templated class instantiated?
References
- DBO_EXTERN_TEMPLATES: https://www.mail-archive.com/[email protected]/msg06963.html
- Wt::Dbo and circular depencies: https://redmine.webtoolkit.eu/boards/2/topics/290?r=292
- The given example is based on the
Wt::Dbotutorial: https://www.webtoolkit.eu/wt/doc/tutorial/dbo.html#_em_one_to_one_em_relations, but I want to place the different classes into different header files.
Based on the answer of ChrisMM, another solution is to forward declare your class at the top of its header file:
Settings.h:
Users.h:
The advantage of this approach is that you only have to forward declare the class in its own header file and are allowed to just include the file in any other (header) file that need it.