如何从包含该类名称的字符串创建一个类的对象?

Posted

技术标签:

【中文标题】如何从包含该类名称的字符串创建一个类的对象?【英文标题】:How create an object of a Class from a string that holds the name of that class? 【发布时间】:2011-07-26 14:04:51 【问题描述】:

假设我有一个字符串,里面有我的班级名称:

mystring = "CDialogChild";

我想创建一个类型名称写在我的字符串中的对象。 我想做类似的事情:

CDialogParent dlg = CDialogParent(mystring);

我的新 dlg 现在创建为 CDialogChild 类型,我可以使用它的方法:

dlg.mycdialogchild_method();

【问题讨论】:

重复***.com/questions/582331/… ***.com/questions/1096700/… 可能重复? “我可以使用它的方法” - 你永远不能使用你的变量类型没有的成员函数。 CDialogParent 没有成员函数 mycdialogchild_method 但是我的 dlg 不是 CDialogParent 类型的!它是 CDialogChild 的类型,而这个有 CDialogChild 顺便说一下,你不需要在类名前加上“C”。这是 Microsoft 用于避免与其他代码发生命名冲突的技术。所以不要重复他们的风格,并防止自己与他们的代码发生冲突。 【参考方案1】:

C++ 中没有任何东西可以为您提供这样的功能(称为反射)。

但是,如果您的类数量有限,您可以使用一些工厂进行某种映射:

class IClassFactory // base interface
 public: 
    virtual ~IClassFactory() 


template< class T >
class ClassFactory  
/* whatever necessary here*/
public:

  T* create();
;


class ClassManager

public:

   void add( std::string name, IClassFactory* factory )  m_map[name] = factory; 

   ACommonBaseClass* create( std::string class_name )  return m_map[class_name]->create();  // this line isn't correct but you get the idea

private:

   std::map< std::string, IClassFactory* > m_map;

;

或者类似的东西(这个写得很快)。

或者,您可以使用允许反射的脚本语言,但这会为您的应用程序添加一个完整的层。可能对嵌入 c++ 感兴趣的脚本语言:ChaiScript、Falcon、Lua、Python、AngelScript、MonkeyScript、Io、...

【讨论】:

【参考方案2】:

一般来说,这在语言中是不可能的,因为 C++ 不是反射语言,它是静态类型的。

作为替代方案,您可以考虑将具有公共基类的相关多态类型的集合硬编码到程序中,并编写一个工厂方法,该方法根据运行时参数创建所需的具体实例。

【讨论】:

【参考方案3】:

有一个设计模式可以完成你的目标:工厂。 您需要比较类名并返回对象:

class MyObject;

MyObject * creator(const std::string& object_name)

  return (object_name == "MyObject") ? new MyObject : 0;

工厂模式略有不同,它使用指向基类的指针并返回子类的实例。

【讨论】:

以上是关于如何从包含该类名称的字符串创建一个类的对象?的主要内容,如果未能解决你的问题,请参考以下文章

(JAVA)啥是实例化如何实现类的实例化(用类或方法创建一个该类的实例)?

Java学习之创建对象内存使用机制

如何取回类的动态创建的对象?

类 Scanner

如何正确地将 JSON 字符串反序列化为包含另一个类的嵌套列表的类

类Scanner