2016-05-01 185 views
2

我有几个类名为Child1,Child2 ...等,从对象父继承。我需要通过名称创建一个对象,例如,如果我有字符串“Child1”,我需要创建对象Child1等等。对象构造函数的C++数组

我想过是这样的:

struct registry_entry { 
    const char* name; 
    IREGISTRY* (*initializer)(); 
}; 

struct registry_entry registry_list[] = 
{ 
    {"xml", &REGISTRY_XML::REGISTRY_XML}, 
} 

但我不能让对象constructor.I的地址相信这个问题一定已经解决了,解决的办法是很简单,但我不能找到它。

+0

你可以使用免费的功能或静态成员函数,而不是构造函数。 – songyuanyao

+0

是的,使用工厂/生成器功能会更简单,更清洁。 – benzeno

回答

6

构造函数和析构函数是特殊函数,不能通过函数指针访问。

您需要创建一个静态成员函数一样

struct REGISTRY_XML { 
    static IREGISTRY* create(); 
}; 

因此,你可以称其为

struct registry_entry registry_list[] = 
{ 
    {"xml", &REGISTRY_XML::create}, 
} 
2

你的代码看起来类似C的非常不很C++ - 样,但如果你实际上可以使用C++ 11的全部功能,那么我会结合使用std::function,lambda,std::unique_ptrstd::map

lambda表达式可以包装构造没有你不必编写单独的包装函数,std::function允许将lambda表达式存储在地图,std::unique_ptr消除了许多存储器管理错误,并std::map执行从字符串初始化剂功能的实际映射。

下面是一个完整的例子:

#include <functional> 
#include <string> 
#include <memory> 
#include <map> 
#include <iostream> 

struct IREGISTRY { 
    virtual ~IREGISTRY() {} 
    virtual void print() = 0; 
}; 

struct REGISTRY_XML : IREGISTRY { void print() override { std::cout << "XML\n"; } }; 
struct REGISTRY_INI : IREGISTRY { void print() override { std::cout << "INI\n"; } }; 
struct REGISTRY_JSON : IREGISTRY { void print() override { std::cout << "JSON\n"; } }; 

int main() 
{ 
    std::map<std::string, std::function<std::unique_ptr<IREGISTRY>()>> const registry_list = { 
     { "xml", []() { return std::make_unique<REGISTRY_XML>(); } }, 
     { "ini", []() { return std::make_unique<REGISTRY_INI>(); } }, 
     { "json", []() { return std::make_unique<REGISTRY_JSON>(); } }, 
    }; 

    auto const initializer_iter = registry_list.find("xml"); 
    if (initializer_iter != registry_list.end()) 
    { 
     auto const initializer = initializer_iter->second; 
     auto const registry_ptr = initializer(); 
     registry_ptr->print(); 
    } 
} 
+0

不幸的是我不能使用C++ 11,只有C++ 03标准。所以我不能使用lambdas(我的项目没有提升,我不想包含它) – Lobster