Почему C ++ не нуждается в предварительных объявлениях для членов класса? - PullRequest
12 голосов
/ 09 сентября 2011

У меня сложилось впечатление, что все в C ++ должно быть объявлено перед использованием.

На самом деле, я помню, что читал, что это причина , почему использование auto в возвращаемых типах недопустимо в C ++ 0x без чего-то вроде decltype: компилятор должен знать объявленный введите перед вычислением тела функции.

Вообразите мое удивление, когда я заметил (спустя долгое время), что следующий код на самом деле совершенно легален:

[Редактировать: измененный пример.]

class Foo
{
    Foo(int x = y);
    static const int y = 5;
};

Так что теперь я не понимаю:

Почему компилятор не требует предварительного объявления внутри классов, когда он требует их в других местах?

Ответы [ 5 ]

10 голосов
/ 09 сентября 2011

Стандарт гласит (раздел 3.3.7):

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

Это, вероятно, достигается путем задержки обработки телвстроенные функции-члены до тех пор, пока не будет проанализировано все определение класса.

6 голосов
/ 09 сентября 2011

Определения функций в теле класса обрабатываются так, как если бы они были фактически определены после того, как класс был определен.Ваш код эквивалентен:

class Foo
{
    Foo();
    int x, *p;
};
inline Foo::Foo() { p = &x; }
3 голосов
/ 09 сентября 2011

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

Почему в C ++ требуется предварительное объявление?

Из-за того, как работает C ++ (включая файлы, а не модули), в противном случае ему нужно будет подождать весь переводческий модуль, прежде чем он сможет точно оценить функции. Здесь есть несколько недостатков:

  • Время компиляции заняло бы еще один хит
  • было бы почти невозможно предоставить какую-либо гарантию для кода в заголовках, поскольку любое введение более поздней функции могло бы сделать ее недействительной

Чем отличается класс?

Класс по определению содержится. Это небольшая единица (или должна быть ...). Поэтому:

  • есть небольшая проблема времени компиляции, вы можете подождать, пока конец класса не начнет анализ
  • нет риска ад зависимости, так как все зависимости четко определены и изолированы

Поэтому мы можем отказаться от этого надоедливого правила предварительного объявления для классов.

2 голосов
/ 09 сентября 2011

Просто угадать: компилятор сохраняет тело функции и фактически не обрабатывает его до тех пор, пока не будет завершено объявление класса.

0 голосов
/ 09 сентября 2011

в отличие от пространства имен, область действия класса не может быть открыта повторно.он ограничен.

представьте себе реализацию класса в заголовке, если все необходимо объявить заранее.я предполагаю, что, поскольку он связан, было бы более логично писать язык таким, какой он есть, вместо того, чтобы требовать от пользователя пересылки вперед в классе (или требовать определения отдельно от объявлений).

...