Подтвердить что ты не робот

Опасно ли создавать виртуальную функцию виртуальной функции?

Предположим, что мы имеем абстрактный класс NonEditableSuperBase, из которого мы создаем еще один абстрактный класс MyBase.

Первый класс NonEditableSuperBase имеет виртуальную функцию (не чисто виртуальную). Однако я хочу заставить это, если кто-то создает класс, который происходит от MyBase, он должен предоставить реализацию указанной функции.

Следовательно, моя идея состоит в том, чтобы определить функцию как чисто виртуальную в MyBase.

Мой вопрос: Это плохая идея, учитывая, что она была просто виртуальной в NonEditableSuperBase?

Пример:

//NonEditableSuperBase.h
class NonEditableSuperBase
{
  ...
  public:
    virtual int someMethod(); //It has an implementation, suppose {return 42;}
};

//MyBase.h
class MyBase: public NonEditableSuperBase
{
  public:
     explicit MyBase();       
     virtual ~MyBase() = default;       
     virtual int someMethod() = 0;  //I make it pure virtual
};

//MyBase.cpp
MyBase::MyBase() : NonEditableSuperBase() { }

//Now someone creates a derived class from MyBase.
class SuperDerived : public MyBase
{
  public:
    explicit SuperDerived();
    int someMethod(); //The user must create an implementation of the function
};

Обновление: Например, в моем случае я хочу создать некоторые производные классы из класса QAbstractTableModel для структуры Qt. Чтобы повторно использовать некоторый код, я хочу создать промежуточный абстрактный класс.

QAbstractTableModel <- MyAbstractModel <- MyModelA (or MyModelB ... etc).

Однако я хочу, чтобы модели (MyModelA, MyModelB) повторно реализовали некоторые из виртуальных функций QAbstractTableModel (например, функция:: index()), поскольку некоторые из дополнительных методов MyAbstractModel требуют определенных реализаций праймерные функции.

4b9b3361

Ответ 1

От ISO IEC 14882 2014:

В § 10.4 говорится:

5 [Примечание: абстрактный класс может быть получен из класса, который не является абстрактным, а чистая виртуальная функция может переопределить виртуальную функцию, которая не является чистой. -end note]

Так что это можно сделать.

Пример использования:

У вас может быть базовый тип, который реализуется как конкретный тип (базовый класс). Теперь, для подтипов, нам может понадобиться дополнительная дополнительная информация. Таким образом, мы можем иметь абстрактный промежуточный объект для удовлетворения наших потребностей.

Ответ 2

[Я предполагаю, что целью было то, что MyBase публично выводит из NonEditableSuperBase, что на самом деле не является примером кода в вопросе.]

Это не кажется опасным, но считайте, что класс, подобный SuperDerived, который происходит из MyBase, может явно использовать реализацию NonEditableSuperBase.

class SuperDerived : public MyBase {
  public:
    using NonEditableSuperBase::someMethod;
    // Or, explicitly:
    // int someMethod() override { return NonEditableSuperBase::someMethod(); }
};

Это удовлетворяет чисто виртуальному требованию, заданному MyBase, но действует точно так же, как если бы у MyBase не было этого требования. Вы заставили автора SuperDerived сделать что-то, но вы фактически не препятствовали им использовать конечную реализацию базового класса.