Wt::Dbo 中的循环依赖

2024-01-07

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

然而,当我使用这个Settings类在另一个cpp文件中,程序无法编译:

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

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

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

  1. 解决方案是包含在User.h在每个包含的 cpp 文件中Settings.h, i.e.:

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

    我不喜欢这个解决方案,因为我必须记住包括User.h每次我包括Settings.h.

  2. 另一种解决方案是使用不推荐的DBO_EXTERN_TEMPLATES宏观,即

    // Settings.h
    ...
    class Settings
    {
    public:
       ....
    };
    
    DBO_EXTERN_TEMPLATES(Settings)
    

    我不喜欢这个解决方案,因为这个宏不推荐,也不记录。DBO_EXTERN_TEMPLATES不适用于所有编译器。

Question

A。克服之间循环依赖的最佳/首选方法是什么Wt::Dbo避免提及的对象undefined class error?

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

我创建了一个新的(一般 - 不Wt::Dbo具体)问题(带有MCVE),以澄清具体情况:模板类的成员函数何时实例化? https://stackoverflow.com/questions/59435038/when-are-member-functions-of-a-templated-class-instantiated

参考

  • DBO_EXTERN_TEMPLATES:https://www.mail-archive.com/[电子邮件受保护]/msg06963.html https://www.mail-archive.com/witty-interest@lists.sourceforge.net/msg06963.html
  • Wt::Dbo 和循环依赖:https://redmine.webtoolkit.eu/boards/2/topics/290?r=292 https://redmine.webtoolkit.eu/boards/2/topics/290?r=292
  • 给出的示例基于Wt::Dbo教程:https://www.webtoolkit.eu/wt/doc/tutorial/dbo.html#_em_one_to_one_em_relations https://www.webtoolkit.eu/wt/doc/tutorial/dbo.html#_em_one_to_one_em_relations,但我想将不同的类放入不同的头文件中。

我不熟悉Wt::Dbo,但我不认为这个问题是特定的。这更像是一个一般的 C++ 类设计问题,您需要解决/处理它;它实际上在 C++ 项目中相当常见。

对于“最佳/首选方法”,这确实是一个见仁见智的问题。就你而言,你实际上可以两者兼得User.h and Settings.h如果您还有前向声明,请相互包括在内。

例如,在Settings.h:

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

class Settings { ... };

Then in User.h, 你可以做:

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

class User { ... };

我知道这看起来很奇怪,但这是一种确保您不必始终包含两个标头的方法。或者,您只需在一个标头中执行此操作,并确保您始终包含该标头。

一般来说,我首选的方法是,在头文件中,仅包含头文件中绝对需要的内容,并向前声明其余部分。然后,我在源文件中包含实际需要的标头。这样做的原因是,如果我需要更改一个头文件,我不必重新编译包含该头文件的所有源文件;它提高了编译过程的性能。

至于您关于为什么解决方案 1 有效的问题,这是因为您包含文件的方式。在该特定示例中,您甚至不需要包括Settings.h在源文件中,因为User.h已经这样做了。但让我们看看预处理器处理完后它会是什么样子。

当你包括User.h,它首先包括Settings.h。包含基本上将内容复制到发生包含的当前文件中。所以,有效地,你的User.h看起来像这样:

// User.h
#include <Wt/Dbo/Dbo.h> // contents from this would be here
#include <string> // contents from this would be here

// Settings.h
#include <Wt/Dbo/Dbo.h> // contents NOT included, due to previous include and include guards
#include <string> // same as above

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

class User
{
public:
  Wt::Dbo::weak_ptr<Settings> settings;

  template<class Action>
  void persist(Action& a)
  {
    Wt::Dbo::hasOne(a, settings);
  }
};

你现在看到的是,当Settings正在定义类,User已经向前声明并且可以被使用Settings班级。什么时候User然后定义,它有完整的定义Settings跟...共事。在你的test.cpp现在归档,两者Settings and User已完全定义,因此可以使用。

我希望这有帮助 :)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Wt::Dbo 中的循环依赖 的相关文章

  • 为什么使用abs()或fabs()而不是条件否定?

    在 C C 中 为什么要使用abs or fabs 不使用以下代码即可查找变量的绝对值 int absoluteValue value lt 0 value value 这与较低级别的指令较少有关吗 您提出的 有条件的abs 并不等于std
  • 检测到 NuGet 包的版本冲突

    我正在开发 ASP Net core 2 1 Web 应用程序项目 我的解决方案中有 1 个项目和 3 个其他库 它是高级架构 数据访问层 DAL 业务层 BL 公共层 CL 所以我需要添加引用来连接一些库和项目 我已经添加了CL参考我的项
  • 将处理后的图形绘制到另一个图形中

    我想将一个经过处理的图形绘制到另一个图形中 I have two graphics var gHead Graphics FromImage h var gBackground Graphics FromImage b Transform
  • 处理 fanart.tv Web 服务响应 JSON 和 C#

    我正在尝试使用 fanart tv Webservice API 但有几个问题 我正在使用 Json Net Newtonsoft Json 并通过其他 Web 服务将 JSON 响应直接反序列化为 C 对象 这里的问题是元素名称正在更改
  • 在 C++11 中省略返回类型

    我最近发现自己在 C 11 模式下的 gcc 4 5 中使用了以下宏 define RETURN x gt decltype x return x 并编写这样的函数 template
  • Guid 应包含 32 位数字和 4 个破折号

    我有一个包含 createuserwizard 控件的网站 创建帐户后 验证电子邮件及其验证 URL 将发送到用户的电子邮件地址 但是 当我进行测试运行时 单击电子邮件中的 URL 时 会出现以下错误 Guid should contain
  • ZLIB 解压缩

    我编写了一个小型应用程序 该应用程序应该解压缩以 gzip deflate 格式编码的数据 为了实现这一点 我使用 ZLIB 库 使用解压缩功能 问题是这个功能不起作用 换句话说 数据不是未压缩的 我在这里发布代码 int decompre
  • Xamarin Android:获取内存中的所有进程

    有没有办法读取所有进程 而不仅仅是正在运行的进程 如果我对 Android 的理解正确的话 一次只有一个进程在运行 其他所有进程都被冻结 后台进程被忽略 您可以使用以下代码片段获取当前正在运行的所有 Android 应用程序进程 Activ
  • 两组点之间的最佳匹配

    I ve got two lists of points let s call them L1 P1 x1 y1 Pn xn yn and L2 P 1 x 1 y 1 P n x n y n 我的任务是找到它们点之间的最佳匹配 以最小化它
  • std::bind 重载解析

    下面的代码工作正常 include
  • C# using 语句、SQL 和 SqlConnection

    使用 using 语句 C SQL 可以吗 private static void CreateCommand string queryString string connectionString using SqlConnection c
  • 从匿名类型获取值

    我有一个方法如下 public void MyMethod object obj implement 我这样称呼它 MyMethod new myparam waoww 那么我该如何实施MyMethod 获取 myparam 值 Edit
  • 是否有一个 C++ 库可以从 PDF 文件中提取文本,例如 PDFBox for Java? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 去年 我使用 PDFBox 在 Java 中创建了一个应用程序来获取某些 PDF 文件中的原始文本 现在
  • gdb查找行号的内存地址

    假设我已将 gdb 附加到一个进程 并且在其内存布局中有一个文件和行号 我想要其内存地址 如何获取文件x中第n行的内存地址 这是在 Linux x86 上 gdb info line test c 56 Line 56 of test c
  • 为什么我使用google'smtp'无法发送电子邮件?

    我有以下程序使用 smtp gmail com 587 发送电子邮件 namespace TestMailServer class Program static void Main string args MailMessage mail
  • Fluent NHibernate 日期时间 UTC

    我想创建一个流畅的 nhibernate 映射来通过以下方式映射 DateTime 字段 保存时 保存 UTC 值 读取时 调整为本地时区值 实现此映射的最佳方法是什么 就我个人而言 我会将日期存储在 UTC 格式的对象中 然后在读 写时在
  • 运行代码首先迁移更新数据库时出错

    我在迁移到数据库时遇到问题 并且似乎找不到我遇到的错误的答案 System MissingMethodException Method not found System Data Entity Migrations Builders Tab
  • boost::program_options:带有固定和可变标记的参数?

    是否可以在 boost program options 中使用此类参数 program p1 123 p2 234 p3 345 p12 678 即 是否可以使用第一个标记指定参数名称 例如 p 后跟一个数字 是动态的吗 我想避免这种情况
  • 如何使用 std::array 模拟 C 数组初始化“int arr[] = { e1, e2, e3, ... }”行为?

    注意 这个问题是关于不必指定元素数量并且仍然允许直接初始化嵌套类型 这个问题 https stackoverflow com questions 6111565 now that we have stdarray what uses are
  • 如何创建向后兼容 Windows 7 的缩放和尺寸更改每显示器 DPI 感知应用程序?

    我是 WPF 和 DPI 感知 API 的新手 正在编写一个在 Windows 7 8 1 和 10 中运行的应用程序 我使用具有不同每个显示器 DPI 设置的多个显示器 并且有兴趣将我的应用程序制作为跨桌面配置尽可能兼容 我已经知道可以将

随机推荐

  • 为什么此代码在到达 StreamReader 的第一个 ReadLine 时挂起?

    我在第一个参数中将一个大文件传递给下面的 SendXMLFile 但由于它导致手持设备 挂起 冻结 我暂时硬编码了一个小得多的文件 3 KB 而不是 1121 KB 供测试用 该文件确实存在 与 exe dll 位于同一文件夹中 如以下代码
  • Iframe 和同源策略以及反向代理黑客

    我一直在阅读具有不同域的 Iframe 然后是父文档 我有点困惑 据我了解 如果 iframe 与其父文档来自同一域 则父文档可以访问 iframe 的文档 看来我可以通过以下技巧来规避这个问题 我在以下位置设置了一个网络服务器mydoma
  • Android:处理ListView回收

    我正在开发一个音板应用程序 在其中使用 Listview Activity 但是由于Android的Listview具有回收其listview的属性 滚动列表视图时 我对所选文本视图所做的更改会反映在所有页面中 我不希望这种事发生 那么我该
  • J2ME 的 JSON 解析器

    我需要一个与 J2ME CLDC 1 1 配合使用的基本 JSON 解析器 Google 搜索返回了大量关于此问题的答案 有些甚至在 stackoverflow 上 但似乎所有内容都指向不再可用的库和解决方案 例如 很多都指向应该位于 js
  • 过滤负时间增量

    考虑一系列持有timedelta64 ns 测量两个事件 A 和 B 之间的时间差 gt time deltas 499900 1 days 23 45 13 499916 1 days 23 50 57 499917 00 03 27 4
  • VB 6:如何执行 .bat 文件但等到其运行完成后再继续?

    VB 6 如何执行 bat 文件但等到其运行完成后再继续 您将需要使用 Win32 API 调用Shell执行Ex http msdn microsoft com en us library bb762154 VS 85 aspx和从SHE
  • 如何处理自动模块中的拆分包?

    我目前正在测试将现有应用程序迁移到 Jigsaw Modules 我的模块之一使用 ElasticSearch 及其 Groovy 插件 org elasticsearch elasticsearch org elasticsearch m
  • boost::spirit 替代解析器返回重复项

    我正在研究https github com F Bergemann RegexSplitter https github com F Bergemann RegexSplitter 目的 解析正则表达式字符串 并创建可破坏和不可破坏的顶级子
  • 将整数数组转换为字符串的最佳方法是什么?

    我想转换一个 int 数组 像这样 1 1 2 1 转换为字符串 1121 最好的 最Pythonic的 方法是什么 我总是可以这样做 然后删除多余的括号 gt gt gt str 1 2 1 1 1 2 1 1 或者我可以这样做 s fo
  • Oracle 数据库变更通知

    我是 DCN 新手 我可以使用它来检测表中列的更新以及该表中的插入吗 我指的是this https docs oracle com cd E11882 01 java 112 e16548 dbchgnf htm JJDBC28815 是的
  • 如何修复div高度

    我正在开发一个聊天控制应用程序 我的问题是这样的 我输入文本 这用于拨打休息电话 获取响应并将其添加到聊天窗口 目前我的问题是这样的 聊天窗口变大 页面随着聊天框 div 一起滚动 有人可以告诉我如何停止整个页面的这种增量吗 简单来说 我的
  • 如何停止R中的for循环并保留数据

    我的代码在日期的 for 循环中运行 该代码需要一段时间才能运行 还剩几天时间 但我迫切需要任何结果 有没有办法打破代码 for 循环 但保留到目前为止已生成的所有数据 是的 您可以按 escape 检查结果 然后重新启动循环 for ii
  • 扩展协议,其中 Self:Swift 中的通用类型(需要 <...> 中的参数)

    我有一个需要泛型的类class Collection
  • 如何将 csv 字符串转换为 pandas 中的列表?

    我正在使用具有以下格式的 csv 文件 Id Sequence 3 1 3 13 87 1053 28576 2141733 508147108 402135275365 1073376057490373 97003854893559701
  • Jquery - 使用 .load 和选择器加载页面不会执行脚本?

    我正在尝试使用 load 方法将一个页面加载到另一页面中 此加载的页面包含一个我想在加载完成后执行的脚本 我整理了一个简单的示例来演示 索引 html
  • MVC:存储库和服务

    我对存储库中定义的内容以及留给服务的内容的限制感到困惑 存储库应该只创建与数据库中的表匹配的简单实体 还是可以使用这些实体的组合创建复杂的自定义对象 换句话说 服务是否应该在存储库上进行各种 Linq to SQL 查询 或者所有的查询都应
  • GSON 将布尔值序列化为 0 或 1

    All 我正在尝试执行以下操作 public class SomClass public boolean x public int y public String z SomClass s new SomClass s x true s y
  • Pandas Multiindex 从索引的第一个条目获取值

    我有以下多索引数据框 from io import StringIO import pandas as pd datastring StringIO File no runtime value1 value2 A 0 0 12 34 A 0
  • 以近乎实时的间隔刷新 RSS 源

    我有一个可以获取几百个 RSS 提要的系统 目前它们的刷新周期为 10 分钟 但我希望能够加快速度 以近实时 推送间隔获取 RSS 源的策略是什么 我遇到的一些解决方案 在 1 分钟时进行一次获取 如果没有变化 则在 2 处再次获取 然后是
  • Wt::Dbo 中的循环依赖

    Wt 建议使用前向声明来避免循环依赖 Settings h include