创建一个具有预定义字符串名称的类的对象

Create an object of a class with a name of predefined string

本文关键字:字符串 预定义 对象 一个 创建      更新时间:2023-10-16

我想创建一个类的对象,该对象的名称为我已知的字符串,即动态。

假设我有一个类A和CCD_ 2所以我应该创建一个对象A ab;但我不能指定"ab",因为它应该像A str一样,因为str可能会动态变化。

您可以使用映射数据结构,键是类的名称,值是用于创建对象的工厂类,或者指向运行时将返回对象的函数的指针。但是,您可能需要将构造的对象强制转换为所需的类型。

示例(为我生疏的C++代码道歉):

首先,我们有一个工厂级的接口

class IObjectFactory 
{
     public:
    virtual ~IObjectFactory() {}
    virtual void* Create() = 0;
};

然后,具体实施。我只做内联。

class ConcreteObjectFactory : public IObjectFactory
{
    public:
    void* Create() { return new ConcreteObject(); }
};

现在看地图。

using namespace std;
map<string, shared_ptr<IObjectFactory> > classMap;
// register the type
classMap["concreteObject"].reset( new ConcreteObjectFactory() );
// using it, albeit you take all kinds of risks if the string is not found
// or points to the wrong type.
ConcreteObject* o = 
    static_cast<ConcreteObject *>( classMap["concreteObject"]->Create() );

有很多方法可以改进这个答案。对于那些感兴趣的人,我建议查看"C++For Games Programmers"中关于RTTI的章节

变量的名称不是程序的一部分,或者更准确地说,该名称不存在于内存中。它只是一个"句柄"或"符号",让程序员可以轻松访问变量,即,查找变量的内容在内存中的位置。

换句话说,在一段代码被编译到对象文件后,这些名称就不存在了。

在您的情况下,"ab"实际上是内存中的内容,当"ab"出现在内存中时,您的程序已经在运行时运行,那时根本没有变量名。

在某些情况下,可以从一个名称转到已经存在的该名称的变量(即,现在不创建它)。这适用于UNIX上的dlsym或Windows上的GetProcAddress。符号必须是可见的,因此是全局的,并且在Windows中从库显式导出。小心名称"篡改"问题。

以这种方式创建一个是不可能的,当然,除了代码生成的变通方法,然后,假设存在编译器,将其构建到库中。

在您的情况下,您可能希望使用从字符串到变量的映射,如果希望同一映射能够存储不同的值类型,则可以使用boost::any作为映射的值类型。

我认为这是不可能的。。如果有人给你答案,你可以用这种方法解决这个问题:

class A {
public:
  A(const std::string& name) : name_(name) {}
  inline std::string name() { return name_; } 
private:
  std::string name_;
}

通过这种方式,您可以实现从字符串到A的隐式转换,因此:

std::string className = "myName";
std::cout << (A)className->name(); /* print "myName" */

否则,您可以按照Extrakun的建议使用地图数据结构。