0

所有,我有一个对象容器,例如,

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++ 中做到这一点?

4

1 回答 1

0

不幸的是,您尝试对对象列表执行的操作对于您设置它们的定义相当困难。设置的一个问题是在编译时没有Rectto的关联Diag,因此您必须告诉编译器 Rectangle 需要特定的构造函数参数。一种解决方案是将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

一般来说,当你不知道如何让编译器做你想做的事情时,你应该问自己是否做对了。在这种情况下,您最好使用应用程序为对象注册回调,或者使指定类型的所有形状都查看中心对象以获取大小信息。

于 2013-06-07T16:49:31.100 回答