Incompatible types prevent overriding

Метод производного класса скрывает virtual метод базового класса вместо того, чтобы заменить его

Описание

Несовместимые типы предотвращают переопределение, происходит, когда метод производного класса имеет то же имя и номер параметров как virtual метод базового класса, но:

  • Отличайтесь по крайней мере по одному типу параметра.

  • Отличайтесь по присутствию или отсутствию спецификаторов, таких как const.

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

Риск

Риски включают следующее:

  • Если вы предназначаете, чтобы метод производного класса заменил метод базового класса, переопределение не происходит.

  • Поскольку метод базового класса скрыт, вы не можете использовать объект производного класса вызвать метод. Если вы используете объект производного класса вызвать метод параметрами базового класса, метод производного класса называется вместо этого. Для параметров, типы которых не совпадают с аргументами, которые вы передаете, бросок происходит, если это возможно. В противном случае отказ компиляции происходит.

Фиксация

Возможные решения включают следующее:

  • Если вы хотите, чтобы метод производного класса заменил метод базового класса, изменил интерфейс метода производного класса.

    Например, измените тип параметра или добавьте const спецификатор при необходимости.

  • В противном случае добавьте линию с помощью Base_class_nameMethodName к объявлению производного класса. Таким образом можно получить доступ к методу базового класса с помощью объекта производного класса.

Примеры

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

class Base {
public:
    Base();
    virtual ~Base();
    virtual void func(float i);
    virtual void funcp(float* i);
    virtual void funcr(float& i);
};

typedef double Float;

class Derived: public Base {
public:
    Derived();
    ~Derived();
    void func(Float i);
    void funcp(Float* i);
    void funcr(Float& i);
};

В этом примере, из-за оператора typedef double Float;, Derived методы класса func, funcp и funcr имейте double аргументы, в то время как Base методы класса с тем же именем имеют float аргументы.

Поэтому вы не можете получить доступ к Base методы класса с помощью Derived объект класса.

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

  1. Перейдите к определению базового класса. На панели Source щелкните правой кнопкой по имени базового класса и выберите Go To Definition.

  2. В определении базового класса идентифицируйте virtual метод, который имеет то же имя как имя метода производного класса.

Коррекция — выводит на экран метод базового класса

Одна возможная коррекция должна использовать тот же тип аргумента в основе и методах производного класса, чтобы позволить заменить. В противном случае, если вы хотите вызвать Base методы класса с float аргументы с помощью Derived объект класса, добавляет линия с помощью Основы:: method_name к Derived объявление класса.

class Base {
public:
    Base();
    virtual ~Base();
    virtual void func(float i);
    virtual void funcp(float* i);
    virtual void funcr(float& i);
};

typedef double Float;

class Derived: public Base {
public:
    Derived();
    ~Derived();
    using Base::func;
    using Base::funcp;
    using Base::funcr;
    void func(Float i);
    void funcp(Float* i);
    void funcr(Float& i);
};
namespace Missing_Const {
class Base {
public:
    virtual void func(int) const ;
    virtual ~Base() ;
} ;

class Derived : public Base {
public:
    virtual void func(int) ;

} ;
}

В этом примере, Derived::func не имеет const спецификатор, но Base::func делает. Поэтому Derived::func не заменяет Base::func.

Коррекция — добавляет const Спецификатор к методу производного класса

Чтобы позволить заменить, добавьте const спецификатор к объявлению метода производного класса.

namespace Missing_Const {
class Base {
public:
    virtual void func(int) const ;
    virtual ~Base() ;
} ;

class Derived : public Base {
public:
    virtual void func(int) const;

} ;
}
namespace Missing_Ref {

class Obj {
    int data;
};

class Base {
public:
    virtual void func(Obj& o);
    virtual ~Base() ;
} ;

class Derived : public Base {
public:
    virtual void func(Obj o) ;

} ;
}

В этом примере, Derived::func принимает Obj параметр значением, но Base::func принимает Obj параметр ссылкой. Поэтому Derived::func не заменяет Base::func.

Коррекция — ссылка использования для параметра метода производного класса

Чтобы позволить заменить, передайте параметр метода производного класса ссылкой.

namespace Missing_Ref {

class Obj {
    int data;
};

class Base {
public:
    virtual void func(Obj& o);
    virtual ~Base() ;
} ;

class Derived : public Base {
public:
    virtual void func(Obj& o) ;

} ;
}

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

Группа: Объектно-ориентированный
Язык: C++
Значение по умолчанию: на
Синтаксис командной строки: VIRTUAL_FUNC_HIDING
Удар: носитель

Введенный в R2015b