【问题标题】:How to convert a string to a class name [duplicate]如何将字符串转换为类名[重复]
【发布时间】:2011-03-27 06:44:43
【问题描述】:

可能重复:
C++: instantiate class from name?

例如,如果我有

string s = "myObject";

那么我怎样才能使用那个 String 来制作这个呢?

return new myObject();

我试过这个,但它很傻而且错了

return new s();

谢谢

【问题讨论】:

  • 您尝试做的事情在 C++ 中很难做到,至少在一般情况下如此。您可能会考虑使用一种更好地支持此类操作的语言。
  • 因为我正在尝试使用工厂模式,我知道这个问题可以用Java解决,但是我正在学习c++所以我想尝试一下
  • @user552279 - 这就是你的答案;使用工厂模式或注册表模式。你可以用谷歌找到大量的例子。
  • 工厂模式只是一个负责创建/实例化对象的类。所以当你需要改变它时,你只会改变一个类。

标签: c++


【解决方案1】:

您可以创建一个简单的工厂并注册您希望能够构建的类。这是一种非常轻量级的反射。

#include <map>
#include <string>

template <class T> void* constructor() { return (void*)new T(); }

struct factory
{
   typedef void*(*constructor_t)();
   typedef std::map<std::string, constructor_t> map_type;
   map_type m_classes;

   template <class T>
   void register_class(std::string const& n)
   { m_classes.insert(std::make_pair(n, &constructor<T>)); }

   void* construct(std::string const& n)
   {
      map_type::iterator i = m_classes.find(n);
      if (i == m_classes.end()) return 0; // or throw or whatever you want
      return i->second();
   }
};

factory g_factory;

#define REGISTER_CLASS(n) g_factory.register_class<n>(#n)

int main()
{
   using namespace std;

   REGISTER_CLASS(string);

   std::string* s = (std::string*)g_factory.construct("string");

   printf("s = '%s'\n", s->c_str());
   *s = "foobar";
   printf("s = '%s'\n", s->c_str());

   return 0;
}

【讨论】:

    【解决方案2】:

    你想要的是virtual constructor (pattern)。语言中此功能的可用性不一定与 VM 解释或管理的语言相关 - 它取决于程序(或库)中存在的类型的信息如何(如果有的话)在运行时可用.在“裸”C++ 中情况并非如此——但它可以被实现,例如 Arvid 所示。问题是这个特性没有标准化的实现,所以每个人都在一次又一次地重新发明它。在某种程度上,COM 或其独立于平台的对应物 XPCOM 在组件级别“标准化”了这一点。

    【讨论】:

      【解决方案3】:

      你不能在 C++ 中这样做,这是设计的。在 c++ 中,类型和对象之间有明显的区别,它们是语言的两个非常不同的实体。因此,您只能实例化一个类型并取回一个对象,并在编译时决定这样做(c++ 不像 c# 或 java 那样提供任何类型的反射系统)。

      但是,您可以将工厂/注册表用于要以这种方式实例化的对象。

      【讨论】:

        【解决方案4】:

        您需要Reflection 来执行此操作。但是 C++ AFAIK 不支持反射。

        有趣的是QT C++ 支持某种反射。查看C# section 了解它是如何在那里完成的,Javascript 有一个功能可以做到这一点。它叫eval()

        【讨论】:

          【解决方案5】:

          使用 C++ 无法做到这一点,因为代码是独立运行的。只有 PHP 等解释型语言或通过解释器运行的程序才允许这种特性。

          【讨论】:

          • Objective-C 是一种编译语言,很容易支持这种行为。
          • Java 已编译,并且很容易做到这一点。
          • 有一些变通方法可以在 C++ 中实现相同的效果。 PO 想要的方式,Objective-C 和 Java 支持这一点,因为有一个 VM 运行它们。
          • 没有运行 Objective-C 的虚拟机。而且我也不认为这对 Java 案例有什么影响。
          • Objective-C not 在 VM 中运行。 Java 在 VM 中运行的事实与它是一种反射语言这一事实​​无关。上次看的时候,Lisp 也编译好了。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-07-26
          • 2012-12-14
          • 1970-01-01
          • 2013-03-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多