Предупреждение для Пропавших без вести виртуального ключевого слова

У меня недавно была расстраивающая проблема, которая свелась к очень простой ошибке кодирования. Рассмотрите следующий код:

#include <iostream>

class Base
{
public:
    void func() { std::cout << "BASE" << std::endl; }
};

class Derived : public Base
{
public:
    virtual void func() { std::cout << "DERIVED" << std::endl; }
};

int main(int argc, char* argv[])
{
    Base* obj = new Derived;
    obj->func();
    delete obj;

    return 0;
}

Вывод

ОСНОВА

Очевидно (для этого случая), я означал помещать виртуальное ключевое слово на Основу:: func так, чтобы Полученный:: func был бы призван основной. Я понимаю, что это (вероятно), позволяется стандартом C++, и возможно с серьезным основанием, но мне кажется, что 99% времени это было бы ошибкой кодирования. Однако, когда я скомпилировал использование g ++ и все-Wblah опции, я мог думать, никакие предупреждения не были сгенерированы.

Существует ли способ генерировать предупреждение, когда и основа и производный класс имеют функции членства того же имени, где функция производного класса является виртуальной, и функция базового класса не?

7
задан Jonesinator 16 December 2009 в 17:47
поделиться

3 ответа

В Visual C ++ вы можете использовать расширение переопределить . Примерно так:

virtual void func() override { std::cout << "DERIVED" << std::endl; }

Это приведет к ошибке, если функция на самом деле не отменяет метод базового класса. Я использую это для ВСЕХ виртуальных функций. Обычно я определяю макрос следующим образом:

#ifdef _MSC_VER
#define OVERRIDE override
#else
#define OVERRIDE
#endif

Поэтому я могу использовать его так:

virtual void func() OVERRIDE { std::cout << "DERIVED" << std::endl; }

Я искал что-то подобное в g ++, но не смог найти похожую концепцию.

Единственное, что мне не нравится. это в Visual C ++ заключается в том, что вы не можете заставить компилятор требовать это (или, по крайней мере, предупреждать) обо всех переопределенных функциях.

5
ответ дан 7 December 2019 в 03:16
поделиться

Я не знаю ни одного флага g ++, который выдавал бы предупреждение об этом (чтобы не сказать, что его нет), но я бы сказал, что это довольно редкая ошибка. Большинство людей сначала пишут базовый класс как интерфейс, использующий чистые виртуальные функции. Если бы вы сказали:

void func() = 0;

, то получили бы синтаксическую ошибку.

3
ответ дан 7 December 2019 в 03:16
поделиться

man gcc

-Woverloaded-virtual (только C ++ и Objective-C ++) Предупреждать, когда объявление функции скрывает виртуальные функции от базового класса. Например, в:

           struct A {
             virtual void f();
           };

           struct B: public A {
             void f(int);
           };

   the "A" class version of "f" is hidden in "B", and code like:

           B* b;
           b->f();

   will fail to compile.
1
ответ дан 7 December 2019 в 03:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: