2013-05-08 28 views
0

我有以下问题需要解决。在编译时决定构造对象

我有组件A.此组件有一些子组件 - B,C,D。使用cmake我正在构建或不构建B,C,D组件。这取决于当前的平台配置。我的cmake系统正在生成可执行的makefile(对于A组件),用于仅链接那些在给定cmake运行中使用的组件。如果构建组件B,则会将其添加到可执行文件中(如果没有) - 未链接。与其他 - C,D相同。

所有这些B,C,D组件都提供了A组件中使用的接口的一些实现。这个A组件应该管理由B,C,D创建的对象,并在适当的时候使用适当的对象将这些对象保存在某个映射中。

问:

我要实现一些简单的和可靠的机制,将这些对象自动实现A接口,同样因为它现在是带有链接 - 链接只是模块,建成。与这些对象相同 - 我希望只有在编译时才将它们注册到A组件中。

我很难解释它。这个想法很容易 - 在编译时建立这些对象的一些映射。只有已编译的组件才能将其对象传送到此地图

+1

您可以使用makefile/cmake系统设置的预处理器指令来解决此问题。例如,如果编译组件B并且在编译A时应该包含组件B,则可以使用指令(如#ifdef COMPILED_B)在必要时在B中包含对B的支持。 – 2013-05-08 13:47:36

+0

是的,这是可能的,但我想在源代码中避免#ifdef。我只是想知道其他人是如何以更复杂的方式来做这件事的。 – user2301299 2013-05-08 14:29:12

回答

1

我已经使用类似于Objective-C和Smalltalk实现方法的设计。

在C++中,方法==成员函数并且必须在编译时定义。所以,尽管接口可以通过预处理器等机制进行扩展,但是相同的配置也必须影响该类的任何客户端,否则它们将无法链接。

所以我使用消息传递系统来调用对象上的方法。因此,如果是主类,并在C和d而非B编译,那么A的消息处理器将只具有由C和D.

这种类型的设计确实需要有注册的处理程序响应消息某种消息系统。有许多现有的系统,如谷歌协议缓冲区和Apache Thrift。我选择设计一个,因为我想要比大多数现有系统允许的更多运行时配置(许多这些消息传递系统都包含IDL编译器)。

但是,它确实使我能够接近OO领域,而不是C++通常允许的混合范式语言。

+0

因此,在你的情况下,已编译(C,D)的组件必须拥有一些全局范围(在进程启动时初始化)的对象,它们将自己注册为某个全局消息调度程序的处理程序?他们是从他们的建设者那里做的? – user2301299 2013-05-08 21:04:28

+1

A的构造函数搜索共享对象的路径。如果它们存在,则加载它们并调用初始化函数(所有组件上的标准名称)。初始化程序通过注册方法名称和相关地址将其功能注入消息传递系统。作为消息的一部分,参数作为键值对携带。可以查询新组件的消息API以获取命令,参数,单位,限制/范围和一些描述的列表。这一点有点复杂,但针对的是大型分布式系统的简单维护。 – 2013-05-08 21:14:28

+0

在一个特定示例中,构造函数被传递一个字符串,该字符串表示此项目的组件目录的路径。然后操作系统的API用于定位和加载共享对象(用于Windows版本的DLL)并动态链接其代码。这些对象包括其作为消息处理程序实现的功能以及可将其功能注入消息传递系统的init函数。指向消息客户端的指针被传递给init函数,以便它可以进行注册调用。 – 2013-05-08 21:23:46