- 论坛徽章:
- 2
|
回复 #1 gengxt001 的帖子
首先, 你要再三的、仔细的思考 : 为什么要这么做。
如果依然需要, C++不适合做这种事情, 可以考虑换其他语言。
如果还是要用C++ …… 要考虑以下一些问题:
1. 工厂
通过一个名字,来创建对象, 需要一个工厂。
注意, 并不一定需要那种OO形式的工厂。
2. 返回类型
工厂到底返回什么?
对于一个需要创建若干种产品的工厂, 返回值是不行的。
只能返回指针。
3. 返回基类指针
可以是一个“抽象层次恰好合适的基类”, 比如:
Shape* createShape(const char* name) {
if (strcmp(name,"circle" )==0)
return new Circle;
if (strcmp(name,"rectangle" )==0)
return new Rectangle;
// ...
}
肯定只能创建“注册过的产品”: 比如上面的 "circle"和 "rectangle"。
如何扩展这种注册方式, 而不是硬编码? 是另一个话题……
现在就可以用字符串来创建对象了:
Shape* /* 注意这里的类型,必须在编译时确定 */ s = createShape(vecType[0].c_str() );
要创建int, string? 可以效仿java的作法, 为基本类型做一个包装器
4. 返回void*
这是C/C++中, 可以泛指一切对象的类型
void* create(const char* name) {
if (strcmp(name,"int" )==0 )
return new int;
if (strcmp(name,"string" )== 0 )
return new std::string;
// ...
}
如何扩展注册方式以及取消硬编码仍不讨论……
使用如下:
void* p = create(vecType[0].c_str() );
*static_cast<int*>(p) = 1212; // 一定要时刻记住p到底指向的是什么类型, 一旦搞错, game over
void* p2 = create(vectype[1].c_str() );
*static_cast<std::string*>(p2) = "1212";
5. boost::any
这是boost提供的一种类型安全的、泛指一切对象的组件。
可以将它想象成其他语言中的object, var之类的东西。
boost::any create(const char* name) {
if (strcmp(name,"int" )==0 )
return int();
if (strcmp(name,"string" )== 0 )
return std::string();
// ...
}
boost::any var = create("int" );
if (int* pi = boost:any_cast<int*>(var)) {
// var里确实是一个int
*pi = 1212;
} else {
// var里不是一个int, 哪出错了
}
boost::any的语法可能不是这样, 我忘了。
6. 销毁
除了boost::any会管理好资源, 其他的都需要自行管理, 比如:
delete s;
delete static_cast<int*>(p); // 一定不要转错了
delete static_cast<std::string*>(p2) // 同上
PS:
B(vector<string> vectType);
这样传参会复制整个vector——包括里面的所有string.
B(const vector<string>& vectType)
怎样?
[ 本帖最后由 OwnWaterloo 于 2009-8-22 12:35 编辑 ] |
|