C++ 如何在C+中执行类型扫描+;?

C++ 如何在C+中执行类型扫描+;?,c++,reflection,scanning,C++,Reflection,Scanning,我有一个ESB。任何序列化消息都传输自己的完全限定名(即命名空间+类名)。每个消息都有一个具体的类型,它封装了要执行的特定逻辑。 每次我收到一条消息时,我首先需要对它进行反序列化,这样我就可以执行它的操作——再一次,取决于它的具体类型——。 我需要一种在编译时或应用程序初始化期间注册每个类的方法。 在.NET中,我会用反射来扫描程序集,在初始化过程中发现消息类型,但是C++中如何使用? < P> C++没有反射能力。我想您可以尝试扫描对象文件等,但没有可靠的方法来做到这一点(AFAIK);编译器

我有一个ESB。任何序列化消息都传输自己的完全限定名(即命名空间+类名)。每个消息都有一个具体的类型,它封装了要执行的特定逻辑。
每次我收到一条消息时,我首先需要对它进行反序列化,这样我就可以执行它的操作——再一次,取决于它的具体类型——。

我需要一种在编译时或应用程序初始化期间注册每个类的方法。

在.NET中,我会用反射来扫描程序集,在初始化过程中发现消息类型,但是C++中如何使用?

< P> C++没有反射能力。我想您可以尝试扫描对象文件等,但没有可靠的方法来做到这一点(AFAIK);编译器可能会完全消除或损坏某些东西


本质上,对于序列化,您必须手动(半)进行注册。但是,您可能会对一个序列化库感兴趣,这将帮助处理这些杂务,例如

< p>因为C++中没有反射,所以我建议使用外部脚本扫描所有相关类的源代码(如果使用空的虚假名定义在源代码中注释它们,那么这是很容易的)。并让它生成注册码。

我个人使用手动注册道路。如果你忘了注册。。。那么,测试无论如何都不起作用

您只需使用工厂,并实现一些标记分派。例如:

typedef void (*ActOnMessageType)(Message const&);

typedef std::map<std::string, ActOnMessageType> MessageDispatcherType;

static MessageDispatcherType& GetDispatcher() {
  static MessageDispatcherType D; return D;
}

static bool RegisterMessageHandler(std::string name, ActOnMessageType func) {
  return GetDispatcher().insert(std::make_pair(name, func)).second;
}
并登记:

bool const gRegisteredFoo = RegisterMessageHandler("Foo", ActOnFoo);
bool const gRegisteredBar = RegsiterMessageHandler("Bar", ActOnBar);

注意:为了允许解耦,我有效地使用了延迟初始化的单例。也就是说,注册是在库加载期间完成的,因此每个
Register…
调用都放在定义函数的文件中。与全局变量的一个区别是,在这里,一旦初始化结束,分派映射实际上是常量。

@VJo,给您:。在Windows平台上,您可以使用COM进行动态类加载。@Space:我对COM知之甚少。但是,您是否仍然需要以某种方式手动注册所有类?@Heandel:
typeid
是关于RTTI或运行时类型信息的。这不是反射。“一点也不。@奥利:事实上,我自己也不太确定,但你可能是对的。只要你没有任何类模板或其他奇怪的东西,这就行了……我认为,从长远来看,与手动注册相比,这项工作相对较少:-)。我发现使用专门的脚本从源代码中提取一些信息并生成代码在某些情况下非常方便。。但这当然要视情况而定。我已经问了一个相关的问题。我的TypeRegistry实际上拥有一个映射,该映射将限定名绑定到能够创建我的具体类型的委托。你认为这没有意义吗?对不起,交叉引用。@why先生:那些日子我倾向于明确。甚至这个机制也不那么明确。我也倾向于注册指向函数的指针,而不是“类型”或“示例”。您的建议是有意义的,但当涉及到解耦时就没有意义了,因为它涉及到元模板编程。
bool const gRegisteredFoo = RegisterMessageHandler("Foo", ActOnFoo);
bool const gRegisteredBar = RegsiterMessageHandler("Bar", ActOnBar);