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

Создание абстрактного класса без каких-либо чистых виртуальных методов

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

Есть ли способ сделать это?

Спасибо

4b9b3361

Ответ 1

Вы можете объявить чистый виртуальный деструктор, но дать ему определение. Класс будет абстрактным, но любые наследующие классы по умолчанию не будут абстрактными.

struct Abstract
{
     virtual ~Abstract() = 0;
};

Abstract::~Abstract() {}

struct Valid: public Abstract
{
        // Notice you don't need to actually overide the base
        // classes pure virtual method as it has a default
};


int main()
{
    // Abstract        a;  // This line fails to compile as Abstract is abstract
    Valid           v;  // This compiles fine.
}

Ответ 2

Укажите конструктор базы как защищенный. Это означает, что вы не можете создать его напрямую, но требует наследования. Однако нет ничего, что могло бы заставить разработчика наследовать этот класс, кроме хорошей документации!

Пример:

struct Abstract {
protected:
    Abstract() {}
};

struct Valid: public Abstract {
    // No need to override anything.
};


int main() {
    // Abstract a;  // This line fails constructor is protected
    Valid v;  // This compiles fine.
}

Ответ 3

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

class Base
{
public:
    virtual ~Base() = 0;
    virtual void SomeVirtualMethod();
};

inline Base::~Base()
{
}

class Derived : public Base
{
};

inline Base* createBase()
{
    // return new Base; // <- This won't compile
    return new Derived; // <- This does compile, Derived is not a pure virtual class !
}

Ответ 4

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

Когда базовый класс необходим, чтобы иметь возможность помещать все "обработчики событий" в std:: set. Тогда никто не может создать класс и поместить его в этот набор без подкласса базового класса. Поскольку набор будет определен как

std::set<MyBaseClass*> mySet;

Ответ 5

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

class abstract { 
        virtual ~abstract()=0; 
}; 

abstract::~abstract() {} 

По умолчанию все наследующие классы не будут абстрактными, хотя им не нужно будет реализовывать какой-либо метод.