Почему чисто виртуальная функция инициализируется 0? - PullRequest
144 голосов
/ 28 января 2010

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

virtual void fun () = 0 ;

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

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

Ответы [ 11 ]

157 голосов
/ 28 января 2010

Причина использования =0 заключается в том, что Бьярн Страуструп не думал, что сможет получить другое ключевое слово, такое как «чистое» прошлое сообщества C ++ во время реализации этой функции. Это описано в его книге Дизайн и развитие C ++ , раздел 13.2.3:

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

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

76 голосов
/ 28 января 2010

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

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

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

29 голосов
/ 28 января 2010

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

pure-specifier:
    = 0

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

19 голосов
/ 28 января 2010

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

15 голосов
/ 28 января 2010

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

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

11 голосов
/ 28 января 2010

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

7 голосов
/ 28 января 2010

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

Не имеет никакого отношения к какому-либо фактическому значению в "vtable". В языке C ++ нет понятия «vtable» или чего-либо подобного. Различные "vtables" - это не более чем детали конкретных реализаций.

3 голосов
/ 28 января 2010

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

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

2 голосов
/ 28 января 2010

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

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

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

2 голосов
/ 28 января 2010

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

...