全部 我有一个容器的容器,例如,
class ShapeBase {};
class Rect: public Shape {
void set(class Diag diag);
};
class Circle: public Shape {
void set(class Radi radi);
};
现在我有一个应用程序类来调用这个形状列表。我的意图是 只会根据参数类型调用列表元素。
像这样的东西。 class application {
typedef std::list<ShapeBase*> List;
List shapeList;
void set(class ???) {
for (List::iterator it = shapeList.begin(); it != shapeList.end(); ++it)
{
// with in the loop of all objects in list,
// only object with matching argument will be called
set(class ???);
};
因此应用程序类根本不知道具体的形状。
如何在C ++中实现?
答案 0 :(得分:0)
不幸的是,当您设置定义时,您尝试使用对象列表进行操作相当困难。建立的一个问题是在编译时没有Rect
与Diag
的关联,所以你必须告诉编译器Rectangles期望特定的构造函数参数。一种解决方案是模板application::set
方法,然后为每个Shape专门化该模板。
下面是一些伪代码(不保证编译):
template<typename ShapeType>
void fillShapeTypeList(std::list<ShapeType*> fillList) {
for (List::iterator it = this.shapeList.begin();
it != this.shapeList.end(); ++it) {
if (ShapeType *shape = dynamic_cast<ShapeType>(*it)) {
fillList.push_back(shape);
}
}
}
template<typename ShapeType, typename ShapeSetter>
void set(ShapeSetter setter) {
std::list<ShapeType*> fillList;
fillShapeTypeList(fillList);
for (std::list<ShapeType*>::iterator it = this.shapeList.begin();
it != this.shapeList.end(); ++it) {
(*it)->set(setter);
}
}
void set(Diag setter) {
set<Rect, Diag>(setter);
}
void set(Radi setter) {
set<Circle, Radi>(setter);
}
在没有使用“替换失败不是错误”模式的Rect
/ Circle
特定设置器的情况下,还有另一种更复杂的方法可以让它工作 - 但这不值得努力对于这种情况。
一般来说,你应该问问自己,如果你没有明白如何让编译器做你想做的事情,你做的是否正确。在这种情况下,您可能最好注册带有应用程序的对象的回调,或者使指定类型的所有形状都查看中心对象以确定信息大小。