Вопрос по static-members, inheritance, virtual, constants, c++ – Можно ли объявить значение виртуальной статической константы в классе C ++?

15

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

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

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

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

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

Заранее спасибо!

Я написал альтернативу на основе шаблонов:stackoverflow.com/a/36797199/1529139 56ka
Полиморфизм работает только для функций-членов и недопустим для элементов данных. Mahesh

Ваш Ответ

1   ответ
15

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) {}
};
Да, это единственное решение, которое я знал до сих пор. Но нет ли способа решить это более изящным / простым способом? Или, если это единственный путь, то мой вопрос скорее таков: какова причина, по которой виртуальное наследование, которое работает с функциями, не будет работать с членами данных? Я понимаю почему на самом делеstatic virtual не имеет смысла, но я не могу понять, почему, скажем так, простойvirtual const int поле не имело бы смысла ... Siska Ádám
@ Siska & # xC1; d & # xE1; m Я опубликовал альтернативу, но я все еще нахожу первый лучше.
Что с ума сошло, в C ++ 11 вы даже можете сделать виртуальную функциюconstexpr, Что не очень полезно, так как он не скомпилируется, когда вы фактически используете виртуальное наследование. Хотьf<A().getID()>(); на самом деле компилируется, учитываяf шаблонная функция, принимающая целое число ...
@ Siska & # xC1; d & # xE1; m, потому что полиморфное поведение не определено для элементов данных. Это способ, которым разработан язык. И это хорошо, ИМО.
@ Siska & # xC1; d & # xE1; m обычно члены обозначают состояние. Если вы используете наследование, вы предполагаете, что класс B является классом A и имеет всех его членов, а также других, но имеет членов A. Не переопределить. Они могут быть разными, но не переопределенными. Я не могу найти пример, где это было бы полезно, кроме того, который вы опубликовали, что, вероятно, не очень хороший дизайн - есть другой механизм, который можно использовать для определения типа объекта во время выполнения (см. RTTI). этоID вещь выглядит как взломать. Может быть, это только я, потому что я не привык к понятию полиморфизма членов данных, но, честно говоря, не вижу никакой утилиты.

Похожие вопросы