c++,抽象类和继承

C++, abstract class and inheritance

本文关键字:继承 抽象类 c++      更新时间:2023-10-16

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

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

这不是我第一次遇到这个问题,但我不记得上次是怎么做的了。这种类可以用于很多事情。这是一个碰撞检测系统。ibbase代表一个抽象的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(ibbase *),这不是我想要的。

这个有什么帮助吗?我明白这个问题,但我想不出解决办法。这是处理它的好方法吗?还是我需要重新考虑我的架构?你会怎么做呢?对于这样的问题,我认为一定存在一种设计模式,但是我没有找到合适的。

谢谢

c++不支持参数的逆变。参见为什么重写没有参数反方差?

您可能最好从doStuff(IBase* base)体中显式地调用doStuff(Base* base)

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

你的虚拟方法:

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

没有重写任何内容。它正在创建一个new虚拟方法,该方法只能从Base向下访问。当你从IBase指针调用doStuff时,它将调用:

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

匹配IBase中定义的签名。

如果你想执行你的foobar函数,你应该对base做一些检查,当它基于覆盖的doStuff时,一旦你确定它是安全的,把它转换为Base*,然后根据需要使用它。

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

最后,如前所述,将doStuff设为public