我是c++的初学者。我遇到了在我正在处理的头文件中使用的覆盖关键字。请问,什么是重写的真正用途,也许用一个例子就容易理解了。


override是c++ 11的关键字,意思是方法是基类方法的“重写”。想想这个例子:

class Foo
{
public:
    virtual void func1();
};

class Bar : public Foo
{
public:
    void func1() override;
};

如果B::func1()签名不等于A::func1()签名,则会生成编译错误,因为B::func1()不会覆盖A::func1(),它将定义一个名为func1()的新方法。

override关键字有两个目的:

它向代码的读者表明“这是一个虚方法,它覆盖了基类的虚方法。” 编译器也知道这是一个覆盖,所以它可以“检查”你没有修改/添加你认为是覆盖的新方法。

为了解释后者:

class base
{
  public:
    virtual int foo(float x) = 0; 
};


class derived: public base
{
   public:
     int foo(float x) override { ... } // OK
};

class derived2: public base
{
   public:
     int foo(int x) override { ... } // ERROR
};

在derived2中,编译器将发出“更改类型”的错误。如果没有重写,编译器最多会给出一个警告,提示“您用相同的名称隐藏了虚拟方法”。

维基百科说:

在面向对象编程中,方法重写是一种语言特性,它允许子类或子类提供已经由它的父类或父类提供的方法的特定实现。

详细地说,当你有一个对象foo,它有一个void hello()函数:

class foo {
    virtual void hello(); // Code : printf("Hello!");
};

foo的子元素也会有一个hello()函数:

class bar : foo {
    // no functions in here but yet, you can call
    // bar.hello()
};

但是,当从Bar对象调用Hello()函数时,您可能希望打印“Hello Bar!”你可以使用override来做到这一点

class bar : foo {
    virtual void hello() override; // Code : printf("Hello Bar!");
};

作为所有答案的补充,供您参考:override不是关键字,而是一种特殊的标识符!它只在声明/定义虚函数的上下文中有意义,在其他上下文中它只是一个普通的标识符。具体操作请参见标准2.11.2。

#include <iostream>

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

struct derived : base
{
    virtual void foo() override
    {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
};

int main()
{
    base* override = new derived();
    override->foo();
    return 0;
}

输出:

zaufi@gentop /work/tests $ g++ -std=c++11 -o override-test override-test.cc
zaufi@gentop /work/tests $ ./override-test
virtual void derived::foo()