0

我正在尝试两个两个处理类实例。我有一个包含 doStuff 方法的抽象基类(此处为 IBase)。此方法将在扩展类中被覆盖,以便处理所有其他定义的类。

这是我正在建造的图书馆的一部分。我希望库用户编写 Base 对象。每个 Base 类都需要通过 doStuff 方法与另一个 Base 对象进行交互。需要容器来处理多个 Base 对象。

这不是我第一次遇到这个问题,但我不记得上次我是怎么做的。这种类可以用于很多事情。在这里,它是一个碰撞检测系统。IBase 代表一个抽象的 HitBox,Container 代表发生碰撞的场景。在这种情况下,Container::process 检查命中框之间的转换,Container::process 用于实现优化算法(四叉树,...)。

我以这种方式构建了这些类:

class IBase {
    public:
        virtual void doStuff(IBase* base) = 0;
}

class Base {
    public:
        virtual void doStuff(Base* base) {
            foobar();
        }
        virtual void doStuff(IBase* base) {
            // irrelevant
        }
}

class Container {
    public:
        void process() {
            for (std::list<IBase*>::iterator it=base_list.begin() ; it!=base_list.end() ; it++) {
                for (std::list<IBase*>::itarator jt=std::next(it) ; jt!=base_list.end() ; jt++) {
                    (*it)->doStuff(*jt);
                }
            }
        }
    private:
        std::list<Ibase*> base_list;
}

但是在循环中,当使用两个 Base 对象时,我无法达到 void Base::doStuff(Base*) 。我只能调用 Base::doStuff(IBase*) 这不是我想要的。

对此有任何帮助吗?我理解这个问题,但我看不到解决方案。这是处理它的好方法还是我需要重新考虑我的架构?你会怎么做?我认为这样的问题必须存在设计模式,但我没有找到合适的。

谢谢

4

2 回答 2

2

C++ 不支持参数的逆变。另请参阅为什么没有用于覆盖的参数逆变?.

您最好doStuff(Base* base)doStuff(IBase* base)体内显式调用。

于 2013-06-10T19:53:24.860 回答
1

*it当从和取消引用时,您的对象*jt被引用为IBase对象,而不是 Base 对象。这意味着只能调用 from 的方法IBase

你的虚拟方法:

virtual void doStuff(Base* base) { ... }

没有压倒一切。它正在创建一个只能从 Base 向下访问的新虚拟方法。当您doStuffIBase指针调用时,它将调用:

virtual void doStuff(IBase* base) { ... }

与中定义的签名匹配IBase

如果你想执行你的函数,你应该对它何时基于覆盖foobar进行某种检查,一旦你确定它是安全的,就将它转换为,然后根据需要使用它。basedoStuffBase*

virtual void doStuff(IBase* base) {
  // not irrelevant
  if (base->isBase()) 
  {
    foobar();
  }
}

最后,如前所述,doStuff公开。

于 2013-06-10T20:14:33.727 回答