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

Avoid dynamic_cast when passing base class as a param to a virtual function

本文关键字:避免 dynamic cast 函数 基类 参数传递      更新时间:2023-10-16

我找不到这个简单但重要的案例的明确答案。(如果有人能给我一个答案,我将不胜感激)。

假设我有两种继承:类 A 是类 B 的基类,类 C 是类 D 的基类,并做额外的工作(知道它实际上是指向 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,但我想不出其他方法来完成我想要的。

我很想听听一些报价 - 也许如何改变设计,甚至"dynamic_cast是必要的"都可以。

我希望我把我的观点说清楚,如果没有 - 我会澄清我的问题。

更新:也许我之前应该提到它(顺便说一句,我不只是编造这个,我实际上不得不在大学里编写这样的东西),但是第五个类的想法,比如 E 将保存一个数组(或列表或其他什么)类型 A,我有一个迭代这个数组的算法, 和那里的每个元素都应该调用这个"foo"方法 - 如果类实际上是 A*,它应该像以前一样操作,如果是 B*,它应该执行类 B 的"foo"。

像这样:

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

谢谢!

要做你想做的事,你需要一个dynamic_cast B::foo。但。。。如果只能用D调用B::foo,则函数不应该超载A::foo. 这样做违反了 LSP,甚至更多或更少违背了面向对象代码的目的。