我无法找到这个简单而重要案例的明确答案。 (如果有人会给我一个答案,我会很感激)。
让我说我有两种继承: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*/);
}
谢谢!
答案 0 :(得分:1)
要做你想做的事,你需要在dynamic_cast
中B::foo
。
但是......如果你只能用B::foo
来调用D
,那么这个函数
不应该超载A::foo
。这样做违反了LSP,以及更多或
少打败面向对象代码的目的。