C ++,抽象类和继承

时间:2013-06-10 19:49:05

标签: c++ inheritance abstract

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

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

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

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

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 *),这不是我想要的。

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

由于

2 个答案:

答案 0 :(得分:2)

C ++不支持参数的逆变。另请参阅Why is there no parameter contra-variance for overriding?

您可能最好从doStuff(Base* base)正文中明确调用doStuff(IBase* base)

答案 1 :(得分:1)

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

您的虚拟方法:

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

并未覆盖任何内容。它正在创建一个 new 虚拟方法,只能从Base向下访问。当您从doStuff指针拨打IBase时,它会致电:

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

IBase中定义的签名相匹配。

如果您要执行foobar功能,当base基于覆盖doStuff时,应对其进行某种检查,并将其投放到{{} 1}}一旦你确定它是安全的,那么根据需要使用它。

Base*

最后,如前所述,将virtual void doStuff(IBase* base) { // not irrelevant if (base->isBase()) { foobar(); } } 公开。