攀升·Uranus


Something Different,Something New
数据加载中……

提问: 可以根据字符串创建类吗


         语言当然是c++了,大家可能都碰到了,在使用工厂的时候其实还是要在某个地方写死new A()这样的代码,我现在想根据配置文件或者其它的途径创建类(类似于JAVA的反射机制);
   
         目标就是,新加入一个类时,我不要改动原来工厂的代码,程序知道新加的类的名字的字符串(通过读配置文件)。

         各位C++大牛们想像办法,实在不可能的话,推荐下国外有没有这种实现的开源项目
         谢谢了!

posted on 2009-01-10 17:13 攀升 阅读(2397) 评论(29)  编辑 收藏 引用

评论

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

C++编译器的RTTI能力很弱。不过如果够猛可以写一个Front专门给各种类加RTTI就好了。
2009-01-10 17:32 | 空明流转

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

@空明流转
是的呀,您指的front是什么类?
2009-01-10 17:52 | 攀升

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

纯靠语言的能力是不行的,可以参考mfc的CObject实现,使用宏来模拟
2009-01-10 18:50 | 飘雪

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

写一个编译器前段,可以给类补充一些代码。
2009-01-10 19:18 | 空明流转

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

语言本身没这个机制,正如3楼说的,可以参见mfc的动态创建。。。
2009-01-10 19:45 | dophi

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

我写了一个宏,过会放上来让大家批判批判
2009-01-10 20:00 | 攀升

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

这个应该不难吧
2009-01-10 20:55 | 5748

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

ACDK这个库可以,不过比较大,使用C++语言按照java语言规范来实现的基础库。不过如果走到这一步,大可不比使用C++了。
2009-01-10 20:59 | 万连文

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

Nebula3里的类就有这个特性
http://blog.csdn.net/xoyojank/archive/2008/07/03/2608400.aspx
具体见SDK源码
2009-01-10 23:21 | xoyojank

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

自己构造一个object 类 然后作一套继承的东西。。 可以看看qt的实现。
2009-01-10 23:36 | kong

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

最简单的办法

A* CreateA(){return new A();}
B* CreateB(){return new B();}

CreatorMap Map;
Map.Add("A",CreateA());
Map.Add("B",CreateB());

-------------------------------

A* b=Map.Create("A");
B* b=Map.Create("B");

-------------------------------

如果你熟悉模板的话,可以实现的更漂亮一点。
2009-01-11 00:55 | 陈梓瀚(vczh)

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

赞同3楼和5楼。移植MFC的RTTI并不难。
2009-01-11 09:26 | Jeff Chen

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

@陈梓瀚(vczh)
这个叫object factory吧,你只能解决已知的类,

问题在于我的工厂也不知道要构造哪些类(根据配置文件读)

Map.Add("A",CreateA());
添加A的前提是你知道有A这个类了,你在头文件里面写了
#include <A.h> 而我的需求是在添加的新类后,不能修改原来的所有代码

我现在的情况是,工厂只有所有要添加类的基类#include<base.h>
添加的新类要把他自己的指针注册给工厂的map<int, Base*>
2009-01-11 12:11 | 攀升

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

C++的反射功能是很弱的,一般而言,都是通过序列化来支持数据成员的构造,如果你还要支持成员函数(也就是你说的未知类),那就由强类型系统变成了弱类型系统。这个最好还是结合一个成熟的脚本系统来做吧,比如python等。我推荐Qt, 你可以通QtScript来使用JavaScript,配置文件可以通过Json。
2009-01-11 12:35 | eXile

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

C++无法解决未知的类,除非你想办法让他们变成已知。譬如说插个DLL什么的。

关于你的问题,singleton也是一种办法。你要知道,除了main函数以外,也有很多能够在初始化的时候执行的代码的。
2009-01-11 13:09 | 陈梓瀚(vczh)

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

@eXile
兄弟,你讲的这个太复杂了,
2009-01-11 13:10 | 攀升

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

@陈梓瀚(vczh)
我现在的实现就是把面向构件的方法,把每个扩展的类都编译成.so,通过OpenDLL, 然后调用构造和析构函数
2009-01-11 13:12 | 攀升

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

@陈梓瀚(vczh)
另外像JAVA的反射机制+XML就很好实现,但是C++不行
2009-01-11 13:12 | 攀升

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

@攀升
"我现在的实现就是把面向构件的方法,把每个扩展的类都编译成.so,通过OpenDLL, 然后调用构造和析构函数"

既然如此,为何不用COM呢?

2009-01-11 14:26 | Jeff Chen

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

注意,它是.so
2009-01-11 14:59 | 空明流转

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

@攀升
已经.so的话,我认为在C++里面这样就足够好了。反射就别想了,反正是没有的。你只能绕个弯子做。
2009-01-11 15:08 | 陈梓瀚(vczh)

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

我没看那个MFC的机制,
研究过的博友能不能告诉我,那个方法能不能实现未知类的new
2009-01-11 21:32 | 攀升

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

@攀升
当然可以。
此前,我试过将其移植到Symbian系统上。
2009-01-12 09:23 | Jeff Chen

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

编程如禅——工厂模式的智能化实现(c++)(2)消灭switch/case语句以及由名字创建对象

http://blog.csdn.net/jicao/archive/2006/07/01/861343.aspx
2009-01-12 10:21 | cj

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

#pragma warning (disable:4786)



#include <iostream>

#include <map>

#include <string>



class Shape;



typedef Shape *(*FactoryFunction)();



class ShapeFactory

{

public:

static void Register(std::string name, FactoryFunction instanceFunction)

{m_FactoryFunctions[name] = instanceFunction;};

static Shape * getInstance(std::string name)

{ if (m_FactoryFunctions.count(name)) return m_FactoryFunctions[name]();

else return NULL; }

private:

static std::map<std::string,FactoryFunction> m_FactoryFunctions;

};



std::map<std::string,FactoryFunction> ShapeFactory::m_FactoryFunctions;



class Shape

{

public:

virtual void Draw() = 0;

};



class Circle : public Shape

{

public:

void Draw() { std::cout << "Drawing a Circle......Done" << std::endl; }

static Shape *createInstance() {return new Circle;}

};



class Triangle : public Shape

{

public:

void Draw() { std::cout << "Drawing a Triagnle......Done" << std::endl; }

static Shape *createInstance() {return new Triangle;}

};



int main()

{

ShapeFactory::Register("circle", & Circle::createInstance);

ShapeFactory::Register("Triangle", & Triangle::createInstance);



Shape * pShape = NULL;



pShape = ShapeFactory::getInstance("circle");

if (NULL == pShape)

{

std::cout << "can't find the product in the factory" << std::endl;

delete pShape;

}

else

{

pShape->Draw();

delete pShape;

}

return 0;

}
2009-01-12 10:24 | cj

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

用宏应该可以的,反正你新加了类,不该原来的代码,但是总是要重新编译的哦!

可以用

#define CREATEOBJECT (XXX)

#include <XXX.H>\
XXX CreateObject() \
{ \
return new XXX(); \
} \

这个影子可以考虑下!
2009-01-13 09:53 | 梦在天涯

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

MFC就是啦, 不过是用宏替换的方式
2009-01-13 22:43 | 多多

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

从某个基类派生的类都可以用其类名的字符串创建.
2009-01-13 22:44 | 多多

# re: 提问: 可以根据字符串创建类吗   回复  更多评论   

我使用的是动态链接库的方法。

可以实现这个功能,不是就是每一个类都需要编译成一个单独的文件,

显得比较麻烦!
2009-03-02 15:19 | test

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理