Если хотите, можете представить, что C ++
генерирует typedef для каждого тега
имя, например
typedef class string string;
К сожалению, это не совсем
точный. Хотелось бы, чтобы все было так просто,
но это не так. C ++ не может генерировать такие
typedefs для структур, союзов или перечислений
без внесения несовместимостей
с к.
Например, предположим, что программа на C
объявляет как функцию, так и структуру
именованный статус:
int status(); struct status;
Опять же, это может быть плохой практикой, но
это C. В этой программе статус (по
сам) относится к функции; структура
статус относится к типу.
Если C ++ автоматически генерирует
typedefs для тегов, то когда вы
скомпилировал эту программу как C ++,
компилятор сгенерирует:
typedef struct status status;
К сожалению, это имя типа
конфликт с именем функции и
программа не будет компилироваться. Это
почему C ++ не может просто сгенерировать
typedef для каждого тега.
В C ++ теги действуют как typedef
имена, кроме того, что программа может
объявить объект, функцию или
счетчик с тем же именем и
та же область, что и у тега. В этом случае
имя объекта, функции или перечислителя
скрывает имя тега Программа может
ссылаться на имя тега только с помощью
ключевое слово class, struct, union или
enum (в зависимости от ситуации) перед
название тэга. Имя типа, состоящее из
одно из этих ключевых слов, за которым следует
тег является уточненным спецификатором типа.
Например, struct status и enum
месяц разработаны уточнители типа.
Таким образом, программа на C, которая содержит оба:
int status(); struct status;
ведет себя так же при компиляции как C ++.
Одно только название статуса относится к
функция. Программа может относиться к
введите только с помощью
сложная структура спецификатора типа
состояние.
Так как же это позволяет багам ползти
в программы? Рассмотрим программу в
Листинг 1 . Эта программа определяет
класс foo с конструктором по умолчанию,
и оператор преобразования, который
преобразует объект foo в char const *.
Выражение
p = foo();
в main должен создать объект foo
и применить оператор преобразования.
последующий оператор вывода
cout << p << '\n';
должен отображать класс foo, но это
не делает. Отображает функцию foo.
Этот удивительный результат происходит потому, что
программа включает в себя заголовок lib.h
показано в Листинг 2 . Этот заголовок
определяет функцию также с именем foo.
имя функции foo скрывает имя класса
foo, поэтому ссылка на foo в основном
относится к функции, а не к классу.
Главное может относиться к классу только
используя разработанный спецификатор типа, как
в
p = class foo();
Способ избежать такой путаницы
на протяжении всей программы, чтобы добавить
следующий typedef для имени класса
Foo:
typedef class foo foo;
непосредственно перед или после урока
определение. Этот typedef вызывает
конфликт между именем типа foo и
имя функции foo (из
библиотека), которая вызовет
ошибка времени компиляции.
Я не знаю никого, кто на самом деле пишет
эти typedefs как само собой разумеющееся.
Это требует много дисциплины. поскольку
частота ошибок, таких как
один в Листинг 1 , вероятно, довольно
маленький, вы много никогда не сталкиваетесь
Эта проблема. Но если ошибка в вашем
программное обеспечение может привести к травмам,
тогда вы должны написать typedefs нет
Неважно, как маловероятна ошибка.
Я не могу представить, почему кто-то когда-либо
хотите скрыть имя класса с
имя функции или объекта в том же
сфера как класс. Правила сокрытия
в С были ошибки, и они должны
не были распространены на классы в
C ++. Действительно, вы можете исправить
ошибка, но это требует дополнительных
дисциплина программирования и усилия, которыене должно быть необходимости.