【问题标题】:How to Use Override Virtual Methods Using Inherited Classes如何使用继承类使用重写虚拟方法
【发布时间】:2016-01-06 12:52:35
【问题描述】:

问题

我想使用继承的类覆盖虚拟方法。

示例

#include <iostream>

class BaseClass
{   
public:
  void PressButton()
  {
    Nuke();
  }

  virtual void Nuke()
  {
    std::cout << "KABOOM" << std::endl;
  }
};

class BigNuke
{
public:   
  void Nuke()
  {
    std::cout << "MASSIVE KABOOM" << std::endl;
  }
};

class ChildClass : public BaseClass, public BigNuke
{
public:
  /*
  void Nuke()
  {
    std::cout << "MASSIVE KABOOM" << std::endl;
  }
  */
};

我的主要看起来像这样:

BaseClass().PressButton();
ChildClass().PressButton();

输出:

KABOOM
KABOOM

现在我知道如果我的子类不继承自 BigNuke 并且我取消注释掉那个 nuke 方法,我得到了我所期望的:

KABOOM
MASSIVE KABOOM

那么当从另一个类继承时,我如何获得MASSIVE KABOOM 呢?我看到它的唯一方法是BigNukeBaseClass 继承,但我不想要这个。在我的实际应用程序中,我有许多不同的基类和许多不同类型的大核弹,所有这些都可以混合和匹配。

【问题讨论】:

  • 详细说明,为什么不赞成?这是一个完整的例子
  • 你为什么期望BigNuke::Nuke()被调用,除非你真的决定在ChildClass中的一个被覆盖的函数中这样做?
  • 是的,我也不明白反对票。
  • 你不能这样做,除非你将BigNuke 设为BaseClass 的子类,因为BigNukeBaseClass 不相关,它们在BigNuke::Nuke 之间没有联系和BaseClass::Nuke。唯一的方法是在ChildClass::Nuke 中调用BigNuke::Nuke
  • 如果您使用 CRTP 定义调用多态函数的基类,即使通过不同的路径继承,它们也可以轻松调用正确的基类。或者,CRTP 可用于覆盖虚拟函数(以调用继承的版本),其总源代码少于在单个子类中这样做。

标签: c++ inheritance


【解决方案1】:

你想做的是“不可能”。它们在 C++ 中没有“按名称链接”这样的东西。基本上,您的代码相当于:

class A {
public:
    void f () { g(); }
    virtual void g () { }
};

class B {
public:
    void h () ;
};

class C: public A, public B { };

而你想在A 中访问B::h,但AB::h 一无所知。将 B::h 更改为 B::g 不会改变任何内容,因为这些只是名称(C++ 中没有动态绑定之类的东西)。

做你想做的事情的一种方法是覆盖C::g并在其中调用B::h

class C {
public:
    virtual void g () { B::g(); }
};

如果你有很多像BC 这样的类,你可能需要使用模板:

template <typename T>
class _C: public A, public T {
public:
    virtual void g () { T::g(); }
};

class C: public _C <B> { };

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-18
    • 2011-10-03
    • 2015-03-23
    • 2013-11-19
    • 2015-09-09
    • 2014-08-21
    • 1970-01-01
    • 2011-10-15
    相关资源
    最近更新 更多