根据类名动态创建类

hyp3388191 2011-12-11 12:31:09
目标:
输入一个类名,如果这个类名存在,就创建该类的一个实例,否则,什么也不做。

#include "stdafx.h"
#include <afx.h>
#include <iostream>
#include <string>
using namespace std;

class A
{
public:
A()
{
cout<<"A class create !"<<endl;
}
};

class B
{
public:
B()
{
cout<<"B class create !"<<endl;
}
};

//
void* Create(string& classname)
{ //这里怎么实现?或者有更好解决方法?
void* pMyclass;
CRuntimeClass* pclass = RUNTIME_CLASS(classname);//这里报错。
pMyclass = pclass->CreateObject();
return pMyclass;
}

//工厂模式,缺点是如果增加另一个类C,必须修改工厂代码。
//目标是当添加一个新类时,不用修改原有代码,所以该方法弃而不用。
void* FactoryCreate(string &classname)
{
void* pMyClass = NULL;

if (classname == "A")
pMyClass = new A;
else if (classname == "B")
pMyClass = new B;
// else if (classname == "C") 新增加一个类C必须添加这一条件分支
// pMyClass = new C;
else
pMyClass = NULL;

return pMyClass;
}

int _tmain(int argc, _TCHAR* argv[])
{
string str;

cin>>str;
A *pA = (A*)Create(str);
delete pA;

cin>>str;
B *pB = (B*)Create(str);
delete pB;

system("pause");
return 0;
}
...全文
254 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
来个纯C++的,不要宏的。

C/C++ code

#include <map>
#include <iostream>
#include <string>

class factory
{
struct abs_generator
{
virtual ~abs_generator(){}
virtual void * constructor……
[/Quote]

我调用的时候,为什么报错? 错误时这样的:error C2062: type 'int' unexpected
fjwzyy 2011-12-13
  • 打赏
  • 举报
回复
3楼的下面这两行代码没有问题吗

//创建
int * p = f.make("int");
std::string * str = f.make("string");

f.make("xx")出来的是一个对象, 而现在编译器将尝试将对象转换为对象的指针, 我想编译器应该有报错吧.
Jinhao 2011-12-13
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 fjwzyy 的回复:]

3楼的下面这两行代码没有问题吗

//创建
int * p = f.make("int");
std::string * str = f.make("string");

f.make("xx")出来的是一个对象, 而现在编译器将尝试将对象转换为对象的指针, 我想编译器应该有报错吧.
[/Quote]

不会有问题. f::make创建一个obj_wrapper对象, 而obj_wrapper提供一个转换函数模板
template<typename T> operator T*();
所以 int * p = f.make("int"); 这个语句 会产生一个obj_wrapper对象,然后它的转换函数检测到往int指针转换。然后转换的时候,需要判断make的类型是不是int。如果是,就会得到int指针。否则得到空指针。
PointertoPointer 2011-12-11
  • 打赏
  • 举报
回复
候俊杰<深入浅出MFC>第三章,有个控制台程序.模仿动态创建,你看看
Jinhao 2011-12-11
  • 打赏
  • 举报
回复
另外,还有类型检查,可以带来一点点的安全性。例如
int * p = f.make("string");
factory知道,string对象不能由int*引用,因此factory就决定不创建这个string对象,p也就是空指针。
hyp3388191 2011-12-11
  • 打赏
  • 举报
回复
灰常好,再等一会,如果没有更好的方法,分就归你了(我所有的分都给你了,T_T)
mstlq 2011-12-11
  • 打赏
  • 举报
回复
google"工厂模式" 楼主应该可以得到不少启发,呵呵
Jinhao 2011-12-11
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 hyp3388191 的回复:]

3楼好猛,必须要用模板吗?
[/Quote]

可以不用呀,但是麻烦。
比如,你的创建方法,每次添加一个新的类就要修改该方法。多麻烦,你看我的,每次添加一个类,只需要用material这个方法告诉factory就可以了,你可以在任何地方用该方法告诉factory,而不必修改factory的代码
hyp3388191 2011-12-11
  • 打赏
  • 举报
回复
说错了,是2楼
hyp3388191 2011-12-11
  • 打赏
  • 举报
回复
3楼好猛,必须要用模板吗?
羽飞 2011-12-11
  • 打赏
  • 举报
回复
RUNTIME_CLASS貌似是MFC中的,可以用typeid
Jinhao 2011-12-11
  • 打赏
  • 举报
回复
来个纯C++的,不要宏的。


#include <map>
#include <iostream>
#include <string>

class factory
{
struct abs_generator
{
virtual ~abs_generator(){}
virtual void * constructor() = 0;
};

template<typename T>
struct generator: abs_generator
{
void * constructor()
{
return (new T());
}
};

struct obj_wrapper
{
obj_wrapper(abs_generator* ag)
: abs_gen_(ag)
{}

template<typename T>
operator T*()
{
return (dynamic_cast<generator<T>*>(abs_gen_) ?
reinterpret_cast<T*>(abs_gen_->constructor()) : 0);
}
private:
abs_generator * abs_gen_;
};
public:
~factory()
{
for(std::map<std::string, abs_generator*>::iterator i = genmap_.begin(); i != genmap_.end(); ++i)
{
delete i->second;
}
}

template<typename T>
void material(const std::string& str)
{
std::map<std::string, abs_generator*>::iterator i = genmap_.find(str);
if(i == genmap_.end())
genmap_[str] = new generator<T>;
}

obj_wrapper make(const std::string& str)
{
std::map<std::string, abs_generator*>::iterator i = genmap_.find(str);
return obj_wrapper(i != genmap_.end() ? i->second : 0);
}
private:
std::map<std::string, abs_generator*> genmap_;
};

int main()
{
factory f;
//首先设置可以创建类型
f.material<int>("int");
f.material<std::string>("string");

//创建
int * p = f.make("int");
std::string * str = f.make("string");

cout<<*p<<endl;
cout<<*str<<endl;
}

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧