c++ - 虚函数override - override用法




安全地覆盖C++虚拟功能 (6)

使函数抽象,以便派生类没有其他选择而不是重写它。

@Ray您的代码无效。

class parent {
public:
  virtual void handle_event(int something) const = 0 {
    // boring default code
  }
};

抽象函数不能有内联定义的主体。 它必须修改成为

class parent {
public:
  virtual void handle_event(int something) const = 0;
};

void parent::handle_event( int something ) { /* do w/e you want here. */ }

我有一个虚拟函数的基类,我想在派生类中重写该函数。 有什么方法可以让编译器检查我在派生类中声明的函数是否实际覆盖了基类中的函数? 我想添加一些宏,或者确保我没有意外声明一个新函数,而不是覆盖旧函数。

以这个例子:

class parent {
public:
  virtual void handle_event(int something) const {
    // boring default code
  }
};

class child : public parent {
public:
  virtual void handle_event(int something) {
    // new exciting code
  }
};

int main() {
  parent *p = new child();
  p->handle_event(1);
}

这里调用parent::handle_event()而不是child::handle_event() ,因为孩子的方法错过了const声明,因此声明了一个新的方法。 这也可能是函数名称中的拼写错误或参数类型中的一些细微差异。 如果基类的接口发生更改,并且某些派生类未更新以反映更改,那么也很容易发生。

有没有办法避免这个问题,我可以通过某种方式告诉编译器或其他工具来检查这个问题吗? 任何有用的编译器标志(最好用于g ++)? 你如何避免这些问题?


像C#的override关键字不是C ++的一部分。

在gcc中, -Woverloaded-virtual警告用一个名称相同的函数来隐藏一个基类虚函数,但它的签名完全不同,它不会覆盖它。 但它不会保护您免于因功能名称本身错误拼写而无法覆盖功能。


在MSVC中,即使不编译CLR,也可以使用CLR override关键字。

在g ++中,在任何情况下都没有直接的强制执行方式。 其他人已经在如何使用-Woverloaded-virtual来捕获签名差异方面给出了很好的答案。 在将来的版本中,有人可能会使用C ++ 0x语法添加像__attribute__ ((override))或等效语法。


如果基类函数被隐藏,编译器可能会产生警告。 如果有,启用它。 这将捕获常量冲突和参数列表中的差异。 不幸的是,这不会发现拼写错误。

例如,这是Microsoft Visual C ++中的警告C4263。


据我所知,你不能把它抽象化吗?

class parent {
public:
  virtual void handle_event(int something) const = 0 {
    // boring default code
  }
};

我以为我在www.parashift.com上读到你实际上可以实现一个抽象方法。 对我个人来说这是有道理的,它唯一做的事情就是强制子类来实现它,没有人说它没有被允许有一个实现本身。


由于g ++ 4.7,它理解新的C ++ 11 override关键字:

class child : public parent {
    public:
      // force handle_event to override a existing function in parent
      // error out if the function with the correct signature does not exist
      void handle_event(int something) override;
};




virtual-functions