c++ - 如何检测重写虚方法声明中的 "missing" 'virtual' 说明符?

标签 c++ linux gcc virtual

假设您有这个 Base 类:

class Base
{
public:
    virtual void foo();
};

您可以在派生自 Base 的类中覆盖 foo():

class Derived : public Base
{
public:
    virtual void foo();
};

但是,如果您在 Derived::foo() 的声明中“忘记”'virtual':

class Derived : public Base
{
public:
    void foo();
};

你得到完全相同的语义:Derived::foo() 是虚拟的,尽管没有明确声明。

现在,假设您的编码标准规定在这种情况下应明确提及“virtual”。

您是否知道一种简单的方法(在 Linux + gcc 环境中)来检测 Derived::foo() 声明中缺少的“virtual”?

我不知道有任何 gcc 警告检测到这一点。

最佳答案

使用 C++11 override特征。 如果不合适,编译器将输出警告或错误。

与其依赖容易出错的编码标准,不如让编译器为您进行检查。

要回答下面的评论,您必须考虑这两种情况:

  1. 如果具有相同签名和名称的基类方法不是虚拟的,则在方法上放置一个override 限定符将输出错误。
  2. 如果它在层次结构中没有变成虚拟的,它也会输出一个错误。

所以这段代码:

struct A
{
   void foo();
   virtual int bar();
};

struct B : A
{
   virtual void foo(); // If you add override here, it errors, if you forget "virtual" it errors too, later in C
   int bar() override;
};

// Write this for each subclass:
struct C : B
{
   void foo() override; // Fails if B does not have "virtual" keyword
};

同意,这很乏味,因为您必须为每个子类复制类的所有签名(不需要通过实现)。所以,如果你想强制你所有的 child 明确地覆盖他们从基类“覆盖”的所有虚方法,你需要“禁用”子类对基类的继承,就像这样:

#ifndef CheckVirtual
   #define WITH_BASE(X) : public X
#else
   #define WITH_BASE(X) 
#endif

struct A
{
   virtual int bar();
   virtual void baz();
};

//==== \/ This is the hostile code to test \/ ========
struct B WITH_BASE(A)
{
   virtual int bar();
   void baz();
};
//==== End of hostile code ====



//==== \/ Start of enforcer code, you must have one enforcer header per base class to check for 
// Notice that Enforcer must reproduce interface of A
struct Enforcer : B
{
   int bar() override;
   void baz() override; // Error here if CheckVirtual is defined, since B::baz is not virtual.
};

// Or better, some sugar, if you have plenty of child of A, with some macro magic:
template <typename T>
struct VirtualEnforcer_ : T
{
    #include "Your_A_Interface_Here"
};
#define EnforceVirtual(X) VirtualEnforcer_<X> assertVirtual ## X ()

EnforceVirtual(B);
EnforceVirtual(AnotherChildOfA);

关于c++ - 如何检测重写虚方法声明中的 "missing" 'virtual' 说明符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26058232/

相关文章:

c - 从 C 代码获取 ALSA 峰值

linux - Samba 导致 "mount:/is busy"

无参数传递或返回值的 C 程序汇编函数

c++ - 如何从 Windows 代码页码获取 ICU 转换器

c++ - 如何使用特定的 gcc 编译器运行 make 命令?

php - 如何使用多个处理器运行 PHP 脚本

使用 g++ 4.6 和 boost::unordered_map 的 C++11 相关编译错误

gcc - Ubuntu上pcre-8.30的编译错误

c++ - TR2 W.R.T. 的状态和内容C++ 规范

c++ - 对 std::bad_cast::bad_cast() 的 undefined reference