2010-01-28 2 views
133

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

virtual void fun() = 0 ; 

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

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

+12

Обратите внимание, что виртуальные таблицы не является обязательным требованием языка, а только вариант реализации виртуальных методов.Компилятор мог создать ту же абстракцию с другой реализацией (то есть без vtable и без какого-либо элемента, имеющего 0) –

+0

@hype Повторите свой дополнительный вопрос - вот что говорит мой ответ (и несколько других). – 2010-01-28 18:34:52

ответ

147

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

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

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

+1

Итак, это просто синтаксис без какой-либо конкретной причины, выбирающей 0 в качестве значения? Это могло бы быть и другое значение или ключевое слово, а также – mukeshkumar

+3

Да, это просто синтаксис. Я видел много проектов, которые #define PURE = 0, и они скажут виртуальный void Foo() PURE; –

+71

Пожалуйста, держите меня подальше от этих проектов :-) – 2010-01-28 19:03:20

19

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

2

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

11

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

+1

-0: когда у вас нет ничего существенного, чтобы сказать по своему усмотрению, используйте обширную цитату (см. Ответ Джерри Коффина для +1;) –

6

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

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

3

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

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

2

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

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

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

+4

Это на самом деле не так. Нет ничего плохого в предоставлении * определения * для чистой виртуальной функции. Единственное, что '= 0' делает, делает весь класс абстрактным и запрещает * виртуальным * вызовам чистых функций. Не виртуальные вызовы по-прежнему безупречно ОК, когда используется определение (если вы его предоставили). – AnT

1

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

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

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

+1

Даже у меня было подобное мнение, но, поскольку многие из них цитировали стандарты и комментарии Бьярне на том же самом, у нас есть минимальные шансы на аргумент :) – mukeshkumar

27

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

pure-specifier: 
    = 0 

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

+4

+1 для ссылки на стандарт C++. Удивительно, что один из лучших ответов и до сих пор получил только 1 голос. Чтение стандарта должно быть первым шагом для решения вопросов на C++. – mloskot

+6

@mloskot: может быть, потому, что он не отвечает на вопрос OP, просто повторяет ситуацию? –

+6

@just somebody - Он включает стандартную цитату, в которой говорится, что является синтаксисом объявления чистой виртуальной функции и что синтаксис использует pure-specifier '= 0' Что еще вы хотели бы узнать? Это было бы так же, как спрашивать, почему тело функции завернуто с {} Ответ будет, потому что это то, что определяет синтаксис C++. – mloskot

14

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

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

+2

+1 Выглядит разумный ответ – mukeshkumar

+2

+1 для объяснения недостатка введения нового ключевого слова. Это полезно для понимания обоснования, но синтаксис C++ кажется мне абсурдно запутанным, и я бы хотел, чтобы они сделали его более понятным для человека - ключевое слово 'pure' было бы замечательно в моей книге. Во всяком случае, хорошо понимать обоснование. –

+0

@KeithPinson Если вы хотите чистое ключевое слово, вы можете '#define pure = 0'. – jdh8

75

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

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

§13.2.3 Синтаксис

+3

Спасибо за эту цитату Джерри :) – mukeshkumar

Смежные вопросы