我希望这在C ++中是可行的。
我有一个从公共基类继承的类列表(Base)。所有这些都将被编译为链接到我的程序的库的一部分。
我可以添加更多来自Base的类,并在我执行此操作后重新编译所有内容。
当我的程序启动时,它将收集所有类的向量(使用我已经实现的一些预处理方法),从Base实现。
我想要做的事(你现在可能已经猜到了)就是根据字符串名称从这些类创建对象。这可能吗?
此致
标记
答案 0 :(得分:2)
好吧,如果你有一个预处理的所有类的列表,那么你可以创建一个构建对象,它将“知道”每个类,并根据请求构建(通过手动搜索列表)。
答案 1 :(得分:2)
取决于你想要做什么。可能有更好的方法来做你需要做的事,但这是一个过于简单的例子......
#include <string>
using namespace std;
class b1{};
class d1 : public b1{};
class d2 : public b1{};
...
int main(int argc, char* argv[]) {
string name(argv[1]);
b1* b;
if (name == "d1")
b = new d1;
else if (name == "d2")
b = new d2;
}
答案 2 :(得分:0)
当然,但不是你想要的方式。 C ++没有反射,所以你必须自己构建机制:(参见下面的EDIT,它实现了工厂指针的映射)
#include <string>
#include <vector>
#include <memory>
using namespace std;
class Base
{
};
class Dog : public Base
{
};
class Cat : public Base
{
};
int main()
{
typedef vector<string> strings;
strings names;
names.push_back("Dog");
names.push_back("Cat");
names.push_back("Dog");
names.push_back("Cat");
typedef vector<Base*> Bases;
Bases my_objs;
for( strings::const_iterator it = names.begin(), it_end = names.end(); it != it_end; ++it )
{
if( *it == "Dog" )
my_objs.push_back(new Dog);
else if( *it == "Cat" )
my_objs.push_back(new Cat);
}
}
你在C ++中提出的任何解决方案都将从根本上改变上述内容。一种常见的变体是尝试通过执行某种查找来摆脱if
块。这可以使用map
对象来实现,该对象将对象的名称链接到实例化它的函数。关于这种方法需要注意的一点是,地图中的函数指针必须具有相同的签名,这意味着Dog
和Cat
工厂方法必须采用相同数量和类型的参数。这是一个可以使用Boost::Any
(link)或其他英雄方法解决的问题,但这超出了本文的范围。
这是一个实现map
工厂方法指针的解决方案:
#include <string>
#include <vector>
#include <map>
using namespace std;
class Base
{
public:
virtual ~Base() {};
};
class Dog : public Base
{
public:
static Base* make_dog() { return new Dog; }
};
class Cat : public Base
{
public:
static Base* make_cat() { return new Cat; }
};
typedef Base*(*ObjFactoryFn)();
typedef map<string, ObjFactoryFn> Factories;
int main()
{
// set up the map of object factory pointers
Factories factories;
factories["Dog"] = &Dog::make_dog;
factories["Cat"] = &Cat::make_cat;
// build list of objects we want
typedef vector<string> strings;
strings names;
names.push_back("Dog");
names.push_back("Cat");
names.push_back("Dog");
names.push_back("Cat");
// build objects using the factory map
for( strings::const_iterator it = names.begin(), it_end = names.end(); it != it_end; ++it )
{
// construct
Base* my_obj = factories[*it](); // this should use map's "find" method for robustness
// destroy
delete my_obj;
}
}