Wt :: Dbo中的循环依赖 [英] Circular dependency in Wt::Dbo

查看:124
本文介绍了Wt :: Dbo中的循环依赖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Wt建议使用前向声明以避免循环依赖.

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);
  }
};

但是,当我在另一个cpp文件中使用此Settings类时,该程序无法编译:

However, when I use this Settings class in another cpp file, the program doesn't compile:

// test.cpp
#include "Settings.h"

错误:C2079:虚拟"使用未定义的类用户"

error: C2079: 'dummy' uses undefined class 'User'

可能的解决方案(我不喜欢)

  1. 一个解决方案是在每个包含Settings.h的cpp文件中的User.h中包括该文件,即:

  1. A solution is to include in User.h in every cpp file that includes Settings.h, i.e.:

// test.cpp
#include "User.h"
#include "Settings.h"

我不喜欢这种解决方案,因为每次添加Settings.h时都要记住要包含User.h.

I do not prefer this solution, because I have to remember to include User.h every time I include Settings.h.

另一种解决方案是使用非推荐的DBO_EXTERN_TEMPLATES宏,即

Another solution is to use the non-recommended DBO_EXTERN_TEMPLATES macro, i.e.

// Settings.h
...
class Settings
{
public:
   ....
};

DBO_EXTERN_TEMPLATES(Settings)

我不喜欢此解决方案,因为不建议也不记录此宏. DBO_EXTERN_TEMPLATES不适用于所有编译器.

I do not prefer this solution as this macro is not recommend, nor documented. DBO_EXTERN_TEMPLATES doesn't work with all compilers.

问题

a.克服Wt::Dbo对象之间的循环依赖关系以避免提到的undefined class错误的最佳/首选方法是什么?

a. What is the best/preferred methodology to overcome circular dependencies between Wt::Dbo objects avoiding the mentioned undefined class error?

b. 为什么解决方案1.有效?

我创建了一个新的(一般的-不是Wt::Dbo特定的)问题(使用MCVE),以阐明具体情况:

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?

参考

  • DBO_EXTERN_TEMPLATES: https://www.mail-archive.com/witty-interest@lists.sourceforge.net/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::Dbo tutorial: 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.

推荐答案

基于ChrisMM的答案,另一种解决方案是在其头文件的顶部转发声明您的类:

Based on the answer of ChrisMM, another solution is to forward declare your class at the top of its header file:

Settings.h:

Settings.h:

// include guard
class Settings;
#include "User.h"

class Settings { ... };

Users.h:

// include guard
class User;
#include "Settings.h"

class User { ... };

这种方法的优点是,您只需要在自己的头文件中声明该类,然后就可以将该文件包含在需要它的任何其他(头文件)中.

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.

这篇关于Wt :: Dbo中的循环依赖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆