1

如果我有一个基类:

class Base 
{
public:
virtual void Test()=0;
};

并且,在一个动态加载的模块(.so/.dll)中,我实现了一个派生自这个的类:

class SomethingFromBase : Base 
{
...
};

并且,一旦这个库被加载,用户就要求创建一个实例SomethingFromBase(假设我们从 cin. 获得名称),并且,我们不知道SomethingFromBase(即,没有办法只做if(inputstr == "SomethingFrombase") { ... } 有没有办法创建SomethingFromBase 的一个实例?

我相当肯定这在(标准)C++ 中是不可能的,但是,我总是希望 SO 会让我感到惊讶!

如果通过添加一些库可以做到这一点,我仍然想知道它。谢谢!

编辑:见 cdhowie 的回答。实施该技术的指南: http ://www.linuxjournal.com/article/3687?page=0,1 http://www.abstraction.net/ViewArticle.aspx?articleID=67

4

2 回答 2

5

您通常通过要求插件库定义一些结构类型的全局变量来实现这一点,该变量包含指向您可以调用的各种函数的指针。(如 setup、teardown 等)在 setup 函数期间,它们会回调到您的应用程序中的某个“注册”函数,在该函数中它们可以传入一个表示类名称的字符串和一个工厂函数指针,该指针将创建一个执行时的实例。

您将其存储在某个地图中,当用户输入字符串时,您查看地图以查看是否注册了工厂函数。如果是这样,只需调用它。

所以这不是“真正的”反射,但你可以在某种程度上手动破解它。例如,参见 Pidgin,它允许规范协议插件,可以在协议列表中提供许多条目。

编辑: 这是实现类似功能的漂亮指南。我更像是一个 C 人,所以我不能保证它真的很棒或任何东西,但乍一看它看起来不错。我在 Linux 上用 C 语言做过类似的事情,基本方法效果很好。

于 2010-11-20T04:25:27.130 回答
0

有一个地图存储类的对象,以类名为键。所有需要以这种方式创建的类,都需要从某个名为“Creatable”之类的基类派生。添加类对象的代码需要与类的实现一起给出。

//Creatable.h
#define IMPLEMENT_CREATABLE( ClassName ) \
  ObjectMap::Instance().Add( string(ClassName), new ClassName );

//ObjectMap.h. This is a singleton
class ObjectMap
{
  ...........
  map<string, Creatable *> myMap;
  ...........
public:
  void Add( const string &className, Creatable * );
  Creatable * Get( const string &className );
};

//My Class.h
class MyClass : public Creatable
{
  ................
};

//My Class.cpp
IMPLEMENT_CREATABLE(MyClass);


//Client.cpp
string className;
cin>>className;
Creatable *anObject = ObjectMap::Instance().Get( className );
于 2010-11-20T05:23:16.097 回答