Можно ли объявить значение виртуальной статической константы в классе С++?

Я хотел бы иметь базовый класс с постоянным полем (например, уникальный идентификатор, связанный с классом, который не может быть изменен после времени компиляции). Пока что объявление static const будет в порядке. Теперь я хотел бы наследовать этот базовый класс и убедиться, что у детей этого класса есть одно и то же поле, но с их собственными значениями. Как я могу это сделать?

Скажем, я хотел бы иметь базовый класс с именем Base с полем ID, который содержит значение int 0. Тогда я хотел бы иметь классы A, B и C, все из которых являются открытыми дочерними элементами Base, и я хотел бы убедиться, что у этих детей также будут поля ID с соответствующими значениями 1, 2 и 3 (путем создания Конечно, я имею в виду что-то вроде получения ошибки компилятора, если у них нет явно объявленного ID).

Если бы мне удалось создать этот сценарий, я ожидал, что с запросом поля ID указателя Base*, я должен получить разные значения в зависимости от того, был ли указатель создан как new A(), new B() или new C().

Мое предположение заключалось бы в объявлении ID как virtual static const, что, конечно, не имеет смысла и дает ошибку компилятора.

Но что я могу сделать для достижения описанного результата? (Единственное, что я мог себе представить, было бы объявить ID как виртуальную функцию, возвращающую целое число, а затем жестко закодировать значение в тело функции, но я ищу что-то более элегантное.)

Заранее благодарю вас!

Ответы

Ответ 1

A static метод не может быть virtual, и никакие члены данных не могут быть virtual.

Но вы можете скрыть поля static в производных классах и использовать метод virtual для их возврата.

class A
{
public:
    static const int ID = 0;
    virtual int getID() { return A::ID; }
};
class B : A
{
public:
    static const int ID = 1;
    virtual int getID() { return B::ID; }
};

Альтернатива:

class A
{
public:
    A(int id = 0) : ID(id) {}
    const int ID;
    getID() { return ID; }
};
class B : public A
{
public:
    B() : A(1) {}
};