【问题标题】:Unexpected behavior of derived class using parent class member to call overridden member使用父类成员调用重写成员的派生类的意外行为
【发布时间】:2013-11-17 12:06:02
【问题描述】:

我有一个从父类派生的类。它调用父类的成员。然而,由于子类的功能需求,需要修改成员的行为。我是这样写代码的:

class parentClass
{
public:
    void memberA()
    {
        memberB();
    }
    void memberB()
    {
        behaviorParent;
    }
};

class childClass:public parentClass
{
public:
    void memberB()
    {
        behaviorChild;
    }
};

int main()
{
    child naughty;
    naughty.memberA();
}

我期待一个行为Child 来作为结果。然而,相反,程序给了我一个behaviorParent而不是behaviorChild。你知道这是为什么吗?还有,如何在不复制父成员代码的情况下修复它?

【问题讨论】:

  • A() 方法是什么?
  • 请插入真实代码,这不会编译
  • 这只是一个例子。如果需要编译,将 memberB 更改为 cout 即可。但我不认为这对提出问题有多大帮助,所以我没有这样做......
  • A() 和 B() 有自己的用途。原始代码很长。但这里只表示 classParent 和 classChild 共享一个确切的 A() 但不同的 B()。

标签: c++ class inheritance overriding


【解决方案1】:

parentClass::memberB 未声明为 virtual。因此,编译器假定从parentClass::memberAmemberB 的调用引用parentClass::memberB

要告诉编译器对memberB 的调用应该引用在派生类中定义的memberB(如果存在这样的函数),请将parentClass::memberB 声明为

virtual void memberB();

【讨论】:

  • 所以如果在父类中,memberB被定义为虚拟,那么即使我不重新定义memberA(因为除了被调用的memberB的行为改变之外,子类的memberA没有任何变化,所以我真的不想重写代码),childClass::memberB会被memberA调用吗?
  • 是的;试试看,你会看到的。
【解决方案2】:

派生类中没有child::A()。所以它将是基础版本。如果你想要别的东西,你需要在派生类中覆盖child:A()

【讨论】:

  • Child::A() 和 Parent::A() 具有相同的行为,重新定义只会重复代码,你不觉得吗?实际上正如 Oswald 所建议的,我只需要在 classParent 中使用虚拟成员。 :)
【解决方案3】:

您正在使用基类中的memberA() 方法。基类中的这个方法不知道你在孩子中实现了什么。这就是为什么它仍然从基类调用memberB()

如果您不想更改基类代码,则必须在子类中覆盖 memberA() 方法。

您可以找到example of overriding in C++ here

【讨论】:

  • 两个类的 A() 具有相同的行为。我看不到重新定义它的原因。正如奥斯瓦尔德建议的那样。我应该在 classParent 中使用虚拟成员。
  • 我知道您需要在不修改父类代码的情况下执行此操作。
猜你喜欢
  • 1970-01-01
  • 2016-05-21
  • 2017-12-02
  • 2017-11-08
  • 2011-06-22
  • 2018-11-30
  • 1970-01-01
  • 2013-10-08
  • 2017-05-17
相关资源
最近更新 更多