Почему чистая виртуальная функция инициализируется 0?

Мы всегда объявляем чистую виртуальную функцию как:

virtual void fun () = 0 ;

I.e., он всегда присваивается 0.

Я понимаю, что для инициализации записи vtable для этой функции значение NULL и любое другое значение здесь приводит к ошибке времени компиляции. Правильно ли это понимание?

Ответ 1

Причина =0 заключается в том, что Bjarne Stroustrup не думал, что он мог получить другое ключевое слово, например, "чистое" прошлое сообщества С++ в момент реализации этой функции. Это описано в его книге The Design and Evolution of С++, раздел 13.2.3:

Был выбран синтаксис curious = 0... потому что в то время я не видел никаких шансов получение нового ключевого слова.

Он также явно заявляет, что для этого не нужно устанавливать значение vtable в NULL, и это не лучший способ реализации чистых виртуальных функций.

Ответ 2

Как и в большинстве вопросов "Почему" о дизайне С++, первое, что нужно посмотреть, это "Дизайн и эволюция С++", Bjarne Stroustrup 1:

Был выбран любопытный синтаксис =0над очевидной альтернативой введение нового ключевого слова pure или abstract, потому что в то время, когда я видел нет возможности получить новое ключевое слово принято. Если бы я предложил pure, Релиз 2.0 отправлен без абстрактные классы. Учитывая выбор между более сильным синтаксисом и абстрактным классов, я выбрал абстрактные классы. Вместо того, чтобы рисковать задержкой и повлекшие определенные бои pure, я использовал традицию C и С++ соглашение об использовании 0 для представления "не там." Синтаксис =0 соответствует мое мнение о том, что тело функции является инициализатор для функции также с (упрощенное, но обычно адекватное) представление набора виртуальных функций реализуется как вектор указатели функций. [...]

1 §13.2.3 Синтаксис

Ответ 3

Раздел 9.2 стандарта С++ дает синтаксис для членов класса. Он включает в себя эту продукцию:

pure-specifier:
    = 0

Нет ничего особенного в значении. "= 0" - это просто синтаксис для выражения "эта функция является чистой виртуальной". Это не имеет ничего общего с инициализацией или нулевыми указателями или числовым значением ноль, хотя сходство с этими вещами может иметь мнемоническое значение.

Ответ 4

Я не уверен, есть ли смысл в этом. Это просто синтаксис языка.

Ответ 5

С++ всегда уклонялся от введения новых ключевых слов, поскольку новые зарезервированные слова прерывают старые программы, которые используют эти слова для идентификаторов. Он часто видел одну из сильных сторон языка, которая, насколько это возможно, уважает старый код.

Синтаксис =0 действительно мог быть выбран, так как он похож на установку записи vtable на 0, но это чисто символическое. (Большинство компиляторов назначают такие записи vtable заглушке, которая испускает ошибку, прежде чем прерывать программу.) Синтаксис был выбран главным образом, потому что раньше он не использовался ни для чего, и он сохранил введение нового ключевого слова.

Ответ 6

С++ должен иметь способ отличить чистую виртуальную функцию от объявления нормальной виртуальной функции. Они решили использовать синтаксис = 0. Они просто могли бы легко сделать то же самое, добавив чистое ключевое слово. Но С++ довольно не хочет добавлять новые ключевые слова и предпочитает использовать другие механизмы для внедрения функций.

Ответ 7

В этом случае ничто не "инициализировано" или "назначено" нулем. = 0 только в синтаксической конструкции, состоящей из токенов = и 0, которая абсолютно не связана ни с инициализацией, ни с присвоением.

Он не имеет никакого отношения к какому-либо фактическому значению в "vtable". Язык С++ не имеет понятия "vtable" или любого подобного. Различные "vtables" - это не что иное, как просто детали конкретных реализаций.

Ответ 8

Я помню, как читал, что оправдание забавного синтаксиса заключалось в том, что было проще (с точки зрения принятия стандартов), чем вводить другое ключевое слово, которое будет делать то же самое.

Я считаю, что это упоминалось в "Проекте и эволюции С++" Бьярне Страуструпа.

Ответ 9

Я бы предположил, что это всего лишь часть грамматики С++. Я не думаю, что существуют какие-либо ограничения на то, как компиляторы действительно реализуют это для данного конкретного двоичного формата. Вероятно, вы предпочли бы правильные компиляторы С++ на раннем этапе.

Ответ 10

= 0 объявляет чистую виртуальную функцию.

Понятно, что для инициализации записи vtable для этой функции значение NULL и любое другое значение здесь приводит к ошибке времени компиляции

Я не думаю, что это правда. Это просто специальный синтаксис. Vtable определяется реализацией. Никто не говорит, что запись vtable для чистого члена должна быть фактически обнулена при построении (хотя большинство компиляторов обрабатывают похожие на vtables).

Ответ 11

Ну, вы также можете инициализировать запись vtable, чтобы указать на фактическую функцию "

 virtual void fun()
 {
     //dostuff()
 }

Кажется интуитивным, что запись vtable может быть определена так, чтобы она не указывала нигде (0) или на функцию. Если вы укажете свое собственное значение, вероятно, это приведет к тому, что он укажет на мусор вместо функции. Но вот почему "= 0" разрешено, а "= 1" - нет. Я подозреваю, что Нил Баттерворт прав, почему "= 0" используется вообще