在基类中调用同名方法

Calling identically named methods in base classes

本文关键字:方法 调用 基类      更新时间:2023-10-16

基类A有一个子类BB有一个子类CA实现了虚拟方法doStuff()B没有,C做到了。从C开始,我想调用AdoStuff()实现(我从CdoStuff()实现中这样做,但这并不重要。我应该打电话吗:

A::doStuff();

或:

B::doStuff();

第一个似乎更清楚,因为它指的是实际的实现。另一方面,如果我后来决定B需要doStuff()A不同,那么第二个可能会更有用。哪个更标准?哪个更危险?

我对B::doStuff()没有触发任何警告感到有点惊讶,但我想根据定义,即使它来自基类,B也有一个实现。基类和实现的链可以任意长和复杂吗?例如,如果我AZ,每个都是前一个的子类,我可以在链中的任何位置实现吗,调用任何类的方法是否只是"链上"直到找到实现?

首先,关于最后一段,是的,你是绝对正确的。

接下来,对于主要问题:

这是一个逻辑问题,应该根据具体情况进行处理。您是唯一可以决定是从B还是从A调用逻辑的人,即使尚未实现B::doStuff()。没有正确的答案。

但是,您应该研究模板方法模式。我的猜测是,如果你想让CA调用一些东西,然后你决定要DC的兄弟姐妹)做同样的事情,你就是在复制代码。所以我会采取不同的方法:

class A
{
private:
   void doAStuff(); //doesn't have to be here
public:
   virtual void doStuff()
   {
      doAStuff();
   }
   void doAStuffAndStuff();
   {
      doAStuff();
      doStuff();
   }
}
class B : A
{
public:
   virtual void doStuff(); //or not
}
class C : B
{
public:
   virtual void doStuff();
}

IMO 这更直观。假设我有A* a,我不知道a的动态类型:

  • 如果我想用派生最多的类中的逻辑调用doStuff(),我调用doStuff()
  • 如果我想用派生最多的类中的逻辑调用doStuff(),但我也想要来自A的逻辑,我调用doAStuffAndStuff()

我说这种方法是一种替代方案。我并不是说它一定适用于你的情况,但它可能。

调用B::doStuff .更好的是,如果可以的话,不要使用需要显式调用基类方法的设计。如果必须,请通过某些宏或别名构造模拟base.doStuff,以防止出现此类错误。您可以在类BaseType定义别名(并确保其在编译时存在),并使用BaseType::doStuff语法。

我对 B::d oStuff() 没有触发任何警告有点惊讶,但我想根据定义,B 有一个实现,即使它来自基类

没有什么可警告的。在您的情况下,这是一个法律场景。

基类和实现的链可以任意长吗 而且复杂

是的,它可以,但它不应该。 需要长继承链的设计,并且包含某种隐藏规则,应该调用什么基类的方法通常会被破坏。