在C++ 11中的析构函数后覆盖标识符

Ent*_*ian 55 c++ overriding virtual-destructor c++11

虚拟析构函数声明后的覆盖标识符是否有任何特殊含义?

class Base
{
public:
    virtual ~Base()
    {}

    virtual int Method() const
    {}
};

class Derived : public Base
{
public:
    virtual ~Derived() override
    {}

    virtual int Method() override // error: marked override, but does not override - missing const
    {}
};
Run Code Online (Sandbox Code Playgroud)

在虚方法上使用覆盖标识符作为检查非常有用:当Base虚方法实际上未被覆盖时,编译器将报告错误.

虚拟析构函数上的覆盖是否也有任何含义/功能?

Man*_*rse 43

是.如果基础析构函数不是虚拟的,则override标记将导致程序无法编译:

class Base
{
public:
    ~Base()
    {}
};

class Derived : public Base
{
public:
    virtual ~Derived() override //error: '~Derived' marked 'override' but does
                                //        not override any member functions
    {}
};
Run Code Online (Sandbox Code Playgroud)

  • 有没有理由一起使用`virtual`和`override`?析构函数有特殊情况吗?我认为常规的智慧是*不要*同时使用两者,因为`override`会使普通方法的"虚拟"冗余,但我不确定析构函数. (9认同)
  • @yano,这是不正确的,如果在基类中将某些内容声明为虚拟的,则在每个派生类中都将其隐式虚拟。但是,您可以在派生类中使用虚拟方法对非虚拟基类方法进行阴影处理(而不是覆盖)。 (2认同)

Joh*_*ing 41

它不override具有特殊含义,而是析构函数本身:

10.3虚函数

6 /尽管析构函数不是继承的,派生类中的析构函数会覆盖声明为virtual的基类析构函数; 见12.4和12.5.

如果将此与前一条款一起使用:

5 /如果使用virt-specifier override标记虚函数并且不覆盖基类的成员函数,则程序格式错误.[例如:

struct B { 
    virtual void f(int); 
}; 

struct D : B
{ 
    void f(long) override; // error: wrong signature overriding B::f
    void f(int) override; // OK 
}; 
Run Code Online (Sandbox Code Playgroud)

- 末端的例子]

你可以看到,如果一个析构函数被标记override但是基类没有virtual析构函数,那么该程序就是格式错误的.

  • 是否建议在派生类中使用override标记析构函数,假设它在基类中是虚拟的?Sutter和Meyers提供了明确的指导原则,指出在覆盖虚函数时应该使用覆盖,但是他们没有专门讨论析构函数.我看不出会有什么伤害,但程序员真的会这样做吗? (13认同)
  • 我在这里错过了什么吗?通常,派生类中的析构函数不会像虚拟方法那样“覆盖”基类中的虚拟析构函数。它是互补的——当对象被拆除时,两个析构函数都会被调用。对我来说,用 override 标记析构函数似乎完全不正确。我认为如果您使用非虚拟析构函数从基类派生,则应将程序视为格式错误。 (3认同)