必须覆盖的虚函数

时间:2014-04-29 12:17:00

标签: c++

考虑具有函数class Base的基类virtual void foo(void)。该功能在Base中实现;即不是纯粹的虚拟。

我是否可以使用哪种模式在继承此类时,即class Child : public Base,迫使我覆盖foo

5 个答案:

答案 0 :(得分:3)

除了使其成为纯虚函数外,无法进行覆盖。

请注意,函数被标记为纯虚拟的事实并不意味着它不能在基类中具有实现 - 这仅意味着派生类必须覆盖它。

struct Base {
    virtual void foo() = 0; // foo() is pure virtual
};
struct Derived : public Base {
    void foo() {            // Derived overrides the pure virtual
        cout << "Hello ";
        Base::foo();    // Call the implementation in the base
        cout << endl;
    }
};

void Base::foo() {
    cout << " world";
}

int main() {
    Derived d;
    d.foo();
    return 0;
}

这将打印"Hello world""world"部分来自基类中的实现。

Demo.

答案 1 :(得分:3)

C ++ 11引入了the override keyword来帮助解决这个问题:

struct Base
{
   void foo();
};

struct Derived : Base
{
   void foo() override;    // error! Base::foo is not virtual
};

但是你不能在Base本身写这个以获得相同的效果;即没有mustoverride说明符。最终,Base关于派生类执行或不覆盖的业务都不是。

可以保持Base摘要,同时为纯虚函数提供“默认”定义:

struct Base
{
   virtual void foo() = 0;
};

void Base::foo() {}

struct Derived : Base {};  // error! does not override Base::foo
struct Derived2: Base
{
   virtual void foo() override
   {
      Base::foo();   // invokes "default" definition
   }
};

如果您要使整个基本类型无法呈现,那么这将是一个可接受的解决方案

答案 2 :(得分:1)

是的,实际上有:

#include <iostream>

class Base
{
public:
    virtual void someFun() {std::cout << "Base::fun" << std::endl;}
    virtual  ~Base() {}
};

class AlmostBase : public Base
{
public:
    virtual void someFun() = 0;
};

class Derived : public AlmostBase
{
public:
    virtual void someFun() {std::cout << "Derived::fun" << std::endl;}  
};

int main()
{
    Derived *d = new Derived();
    d->someFun();
    delete d;
}

如果您从someFun取消注释Derived,编译器会抱怨... 您引入了一个具有纯虚函数的中间类AlmostBase。这样你也可以拥有Base个对象,现在唯一的缺点就是所有的类都需要从中间库继承。

答案 3 :(得分:1)

纯虚拟成员函数仍然可以拥有正文。唯一需要注意的是它必须在类定义之外定义。这是完全合法的C ++:

#include <iostream>

struct Base
{
  virtual void foo() const = 0;
};

void Base::foo() const
{
  std::cout << "Base!\n";
}

struct Derived : Base
{
  // Uncomment following line to remove error:
  //virtual void foo() const override { std::cout << "Derived\n"; Base::foo(); }
};

int main()
{
  Derived d;
  d.foo();
}

Live example

请注意,这使Base在所有方面成为抽象类,即无法直接实例化Base

答案 4 :(得分:0)

你可以让base方法在调用时抛出异常,然后类必须覆盖它以避免父执行。 这在MFC FrameWork中使用,例如

// Derived class is responsible for implementing these handlers
//   for owner/self draw controls (except for the optional DeleteItem)
void CComboBox::DrawItem(LPDRAWITEMSTRUCT)
    { ASSERT(FALSE); }
void CComboBox::MeasureItem(LPMEASUREITEMSTRUCT)
    { ASSERT(FALSE); }
int CComboBox::CompareItem(LPCOMPAREITEMSTRUCT)
    { ASSERT(FALSE); return 0; }

如果控件是所有者绘制的那些方法必须继承,它负责measuer,draw,...如果你在测试函数时错过了它,你会得到一个带有有用信息的断言或异常。