exponenta event banner

Частичное переопределение перегруженных виртуальных функций

Класс переопределяет часть унаследованных виртуальных функций с заданным именем

Описание

Этот дефект возникает в следующих случаях:

  • Базовый класс имеет несколько virtual методы с тем же именем, но различными подписями (перегрузка).

  • Класс, производный от базового класса, переопределяет по крайней мере один из них virtual методы, но не все из них.

Риск

virtual методы, которые не переопределяются производным классом, скрыты. Эти методы нельзя вызывать с помощью объекта производного класса.

Зафиксировать

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

  • В производном классе, если переопределить один virtual метод, переопределить все virtual методы из базового класса с тем же именем, что и этот метод.

  • В противном случае добавьте строку using Base_class_name::method_name к объявлению производного класса. Таким образом, можно вызвать методы базового класса, используя объект производного класса.

Примеры

развернуть все

class Base {
public:
    explicit Base(int b);
    virtual ~Base() {};
    virtual void set()           {
        _b = (int)0;
    };
    virtual void set(short i)    {
        _b = (int)i;
    };
    virtual void set(int i)      {
        _b = (int)i;
    };
    virtual void set(long i)     {
        _b = (int)i;
    };
    virtual void set(float i)    {
        _b = (int)i;
    };
    virtual void set(double i)   {
        _b = (int)i;
    };
private:
    int _b;
};

class Derived: public Base {             
        public:
                Derived(int b, int d): Base(b), _d(d) {};
                void set(int i)    { Base::set(i); _d = (int)i; };
        private:
                int _d;
};

В этом примере класс Derived переопределяет функцию set который принимает int аргумент. Он не переопределяет другие функции с тем же именем set но возьмем аргументы других типов.

Дефект появляется в имени производного класса в определении производного класса. Чтобы найти переопределенный метод базового класса:

  1. Перейдите к определению базового класса. На панели «Источник» щелкните правой кнопкой мыши имя базового класса и выберите «Перейти к определению».

  2. В определении базового класса определите метод, имя и подпись которого совпадают с именем производного метода класса.

Исправление - метод скрытого базового класса

Одной из возможных корректировок является добавление строки. using Base::set в Derived объявление класса.

class Base {
public:
    explicit Base(int b);
    virtual ~Base() {};
    virtual void set()           {
        _b = (int)0;
    };
    virtual void set(short i)    {
        _b = (int)i;
    };
    virtual void set(int i)      {
        _b = (int)i;
    };
    virtual void set(long i)     {
        _b = (int)i;
    };
    virtual void set(float i)    {
        _b = (int)i;
    };
    virtual void set(double i)   {
        _b = (int)i;
    };
private:
    int _b;
};

class Derived: public Base {             
        public:
                Derived(int b, int d): Base(b), _d(d) {};
                using Base::set;
                void set(int i)    { Base::set(i); _d = (int)i; };
        private:
                int _d;
};

Информация о результатах

Группа: Объектно-ориентированная
Язык: C++
По умолчанию: Вкл для рукописного кода, выкл для сгенерированного кода
Синтаксис командной строки: PARTIAL_OVERRIDE
Воздействие: среднее
Представлен в R2015b