C 中可以从类名字符串实例化对象吗?
C 中是否有一种机制可以从表示类名的字符串实例化对象,消除了为工厂中每个潜在的派生类显式定义 if-else 语句的需要类?
问题:
考虑以下类结构:
class Base; class DerivedA : public Base; class DerivedB : public Base; // etc...
以及相应的工厂类 BaseFactory,它创建派生类的实例基于指定类名字符串的类:
class BaseFactory { public: BaseFactory(std::string &sClassName) { msClassName = sClassName; }; Base * Create() { if(msClassName == "DerivedA") { return new DerivedA(); } else if(msClassName == "DerivedB") { return new DerivedB(); } // etc... }; private: string msClassName; };
但是,这种方法需要明确在 BaseFactory 中指定每个派生类,随着派生类数量的增长,这会变得很麻烦。
解决方案:
与 C# 等语言不同,C 本身并不提供一种根据运行时类型信息动态创建对象的机制。为了实现类似的功能,可以考虑在类名和对象创建函数之间构建一个映射:
template<typename T> Base * createInstance() { return new T; } typedef std::map<std::string, Base*(*)()> map_type; map_type map; map["DerivedA"] = &createInstance<DerivedA>; map["DerivedB"] = &createInstance<DerivedB>;
使用此映射,对象实例化变为:
return map[some_string]();
或者,可以注册在程序初始化期间自动派生类:
template<typename T> struct DerivedRegister : BaseFactory { DerivedRegister(std::string const& s) { getMap()->insert(std::make_pair(s, &createT<T>)); } }; // in derivedb.hpp class DerivedB { ...; private: static DerivedRegister<DerivedB> reg; }; // in derivedb.cpp: DerivedRegister<DerivedB> DerivedB::reg("DerivedB");
这种方法消除了手动类注册的需要,因为它会在以下情况下自动发生:类已定义。
总结:
虽然 C 不直接支持从类名字符串实例化对象,但这些技术提供了一种通过映射类来实现类似功能的方法为对象创建函数命名或通过自动化注册过程来命名。
以上是C 可以从类名字符串实例化对象吗?的详细内容。更多信息请关注PHP中文网其他相关文章!