С++: любой способ предотвратить создание экземпляра абстрактного базового класса?

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

Я могу это сделать:

class BaseFoo
{
    virtual void blah() = 0;
};

class Foo : public BaseFoo
{
    virtual void blah() {}
};

но я бы хотел избежать vtable. (согласно мой другой вопрос о виртуальных деструкторах)

Microsoft ATL имеет ATL_NO_VTABLE, чтобы выполнить это (или, по крайней мере, я думаю, что он делает...)

Ответы

Ответ 1

Действительно очевидным способом является объявление защищенного конструктора и объявление публичных конструкторов в не абстрактных производных классах.

Это, конечно, переносит нагрузку на ядро ​​на производные классы, но, по крайней мере, базовый класс защищен.

Ответ 2

Вы можете создать защищенный конструктор

Ответ 3

Если вы создадите защищенный конструктор в соответствии с рекомендациями здесь, то когда ваш производный класс будет создан, вы получите схожую ошибку, "не можете получить доступ к закрытому члену, объявленному в классе", с другой информацией, специфичной для ваших классов.

Если у вас есть чистые виртуальные методы в вашем базовом классе, проблема не в том, что они создаются (и это, конечно, не то, что не абстрактные методы создаются), но проблема возникает во время уничтожения, когда компилятор не может то, что принадлежит вашему производному классу. Это, или вы создали экземпляр без владельца! (ruh roh rhaggy)

Объявите чистый виртуальный деструктор для базового класса, а затем внесите его извне. Кроме того, никогда, никогда не создавайте конструктор private (edit: если только он не будет гарантирован только для внутреннего использования, например, автоматическое построение следующего node в связанном списке). Самое близкое, что вам когда-либо понадобится (изменить: в противном случае) - это явный конструктор (но это другой раздел).

edit: Возможно, я нашел ответ, но сегодня я не могу писать.

// example.h

class A
{

    A ( ) { }
    virtual ~A ( ) = 0;
};

class B : public A
{
    B ( ) { }
    ~B ( ) { }
};

// example.cpp
#include "example.h"

A::~A ( ) { }