将基类作为参数传递给虚函数时避免使用 dynamic_cast
Posted
技术标签:
【中文标题】将基类作为参数传递给虚函数时避免使用 dynamic_cast【英文标题】:Avoid dynamic_cast when passing base class as a param to a virtual function 【发布时间】:2014-03-31 13:47:51 【问题描述】:对于这个简单但重要的案例,我找不到明确的答案。 (如果有人向我推荐答案,我将不胜感激)。
假设我有两种继承: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*/);
谢谢!
【问题讨论】:
你知道你在使用私有继承吗?这里不能有LSP。 '在传递基类时避免 dynamic_cast ...' 选择更好的设计,问题已经闻起来了... 【参考方案1】:要做你想做的事,你需要一个dynamic_cast
in B::foo
。
但是...如果您只能使用D
调用B::foo
,则该函数
不应该超载A::foo
。这样做违反了 LSP,并且更多或
less 违背了面向对象代码的目的。
【讨论】:
以上是关于将基类作为参数传递给虚函数时避免使用 dynamic_cast的主要内容,如果未能解决你的问题,请参考以下文章
为啥当我有两个函数时编译器没有显示错误,一个将基类作为参数,一个将派生类作为参数?
如何将子类作为期望基类的函数的参数传递,然后将该对象传递给指向这些抽象类对象的指针向量?
EXC_BAD_ACCESS(code = 1,address = 0x0)当将std :: map作为参数传递给虚拟函数调用时发生