Саммерфилд Марк
Шрифт:
Имена, вводимые typedef
С++ позволяет с помощью ключевого слова typedef назначать псевдонимы типам данных. Например, если часто используется тип QVector<Point2D> и хотелось бы сэкономить немного на вводе символов (или, к несчастью, приходится иметь дело с норвежской клавиатурой и вам трудно найти на ней угловые скобки), то можно в одном из ваших заголовочных файлов использовать такое объявление typedef:
После этого можно использовать имя PointVector как сокращение для QVector<Point2D>. Следует отметить, что новое имя указывается после старого. Синтаксис typedef специально имитирует синтаксис объявлений переменных.
В Qt имена, вводимые typedef, в основном используются по трем причинам:
• Удобство: Qt объявляет с помощью typedef имена uint и QWidgetList для unsigned int и QList<QWidget *>, чтобы сэкономить несколько символов.
• Различие платформ: определенные типы должны определяться по-разному на различных платформах. Например, qlonglong определяется как __int64 в Windows и как long long на других платформах.
• Совместимость: класс QIconSet из Qt 3 был переименован в QIcon для Qt 4. Для облегчения пользователям Qt 3 перевода своих приложений в Qt 4 класс QIconSet объявляется как typedef QIcon, когда включается режим совместимости с Qt 3.
Преобразование типов
С++ представляет несколько синтаксических конструкций по приведению одного типа к другому. Заключение нужного типа результата в скобки и размещение его перед преобразуемым значением — это традиционный способ, унаследованный от С:
Это очень мощная конструкция. Она может использоваться для изменения типа указателя, устранения константности и для многого другого. Например:
В этом примере мы приводим тип short * к типу char * и используем унарный оператор * для обращения к байту по заданному адресу памяти. В системах с прямым порядком байтов этот байт содержит значение 0x12; в системах с обратным порядком байтов он имеет значение 0x34. Поскольку указатели и ссылки представляются одинаково, не удивительно, что представленный выше программный код можно переписать с приведением типа ссылки:
Если тип данных является именем класса, именем, введенным typedef, или элементарным типом, который может быть представлен одной буквенно—цифровой лексемой, для приведения типа можно использовать синтаксис конструктора:
Приведение типа указателей и ссылок с использованием традиционного подхода в стиле языка С является неким экстремальным видом спорта, напоминающим параглайдинг и передвижение на кабине лифта, потому что компилятор позволяет приводить указатель (или ссылку) любого типа в любой другой тип указателя (или ссылки). По этой причине в С++ введены новые конструкции приведения типов с более точной семантикой. Для указателей и ссылок новые конструкции приведения типов более предпочтительны по сравнению с рискованными конструкциями в стиле С, и они используются в данной книге.
• static_cast<T> может применяться для приведения типа указателя на А к типу указателя на В при том ограничении, что класс В должен быть наследником класса А. Например:
Если объект не является экземпляром В (но все же наследует А), применение полученного указателя может привести к неожиданному краху программы.
• dynamic_cast<T> действует аналогично static_cast<T>, кроме применения информации о типах, получаемой на этапе выполнения (runtime type information — RTTI), для проверки принадлежности к классу В объекта, на который ссылается указатель. Если это не так, то оператор приведения типа возвратит нулевой указатель. Например: