将基类作为参数传递给虚函数时,请避免使用dynamic_cast

时间:2014-03-31 13:47:52

标签: c++ inheritance derived-class virtual-functions dynamic-cast

我无法找到这个简单而重要案例的明确答案。 (如果有人会给我一个答案,我会很感激)。

让我说我有两种继承:A类是B类的基类,C类是D类的Base类,做额外的工作(知道它实际上是指向它的指针) d)。

现在让我们假设A类有一个虚拟功能' foo'它将C的指针作为参数。我想要实现的是每当A调用“foo”时,它就像是有一个指向C的指针,每当B调用foo时,它就好像它有一个指向D的指针。

编译器允许我传递一个初始化的对象,如: C * c = new D(); ,但是在foo'中尽我所能告诉我,没有办法告诉我们在不使用dynamic_cast的情况下确实得到了指向D的指针。

这是我想到的一个草图:

class C {};
class D : C {// has more functions };


class A {

public:
    virtual void foo (C* c) { //do something with c* };

};


class B : A {

public

    virtual void foo (C* c) { // call A::foo()
                              //do something with c knowing that c* as actually a D*
                             }

};

在B :: foo中使用dynamic_cast似乎是不可避免的,以实现我想要的。我知道,一般来说使用dynamic_cast表示糟糕的OOP设计,因为它可能违反LSP,但我无法想到其他方法来实现我想要的。

我很乐意听到一些提议 - 也许会如何改变设计,甚至“动态广播”是必要的'会好的。

我希望我明白我的观点,如果没有 - 我会澄清我的问题。

更新:也许我之前应该提到它(顺便说一句,我不仅仅是在做这件事,我实际上不得不在大学里做这样的事情),但是想到第五节课,假设E将保存A类型的数组(或列表或其他),并且我有一个algorihm,它遍历此数组,并且 那里的每一个元素都应该称之为“foo'方法 - 如果类实际上是A *,它应该像以前一样运行,如果它是B *,它应该执行“foo”#39; B级。

这样的事情:

//within class E
A** arrayOfAs; //(and B's)
for (int i = 0 ; i < lengthOfArray ; ++i ) 
{
    arrayOfAs[i]->foo(/*someObject*/);
}

谢谢!

1 个答案:

答案 0 :(得分:1)

要做你想做的事,你需要在dynamic_castB::foo。 但是......如果你只能用B::foo来调用D,那么这个函数 不应该超载A::foo。这样做违反了LSP,以及更多或 少打败面向对象代码的目的。