QT 4: программирование GUI на С++ - [189]

Шрифт
Интервал

>if (options & CaseSensitive) {

> // поиск с учетом регистра

>}

Переменная типа FindOption может содержать только один флажок в данный момент времени. Результат объединения нескольких флажков при помощи оператора | представляет собой обычное целое число. К сожалению, здесь не обеспечивается защищенность типа: компилятор не будет «жаловаться», если функция, которая должна принимать в качестве параметра типа int некую комбинацию опций FindOption, фактически получит Saturday. Qt использует класс QFlags для обеспечения защищенности своих собственных типов флажков. Этот класс можно также применять при определении пользовательских типов флажков. Подробное описание класса QFlags можно найти в онлайновой документации.

Имена, вводимые typedef

С++ позволяет с помощью ключевого слова typedef назначать псевдонимы типам данных. Например, если часто используется тип QVector и хотелось бы сэкономить немного на вводе символов (или, к несчастью, приходится иметь дело с норвежской клавиатурой и вам трудно найти на ней угловые скобки), то можно в одном из ваших заголовочных файлов использовать такое объявление typedef:

>typedef QVector PointVector;

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

В Qt имена, вводимые typedef, в основном используются по трем причинам:

• Удобство: Qt объявляет с помощью typedef имена uint и QWidgetList для unsigned int и QList, чтобы сэкономить несколько символов.

• Различие платформ: определенные типы должны определяться по-разному на различных платформах. Например, qlonglong определяется как __int64 в Windows и как long long на других платформах.

• Совместимость: класс QIconSet из Qt 3 был переименован в QIcon для Qt 4. Для облегчения пользователям Qt 3 перевода своих приложений в Qt 4 класс QIconSet объявляется как typedef QIcon, когда включается режим совместимости с Qt 3.

Преобразование типов

С++ представляет несколько синтаксических конструкций по приведению одного типа к другому. Заключение нужного типа результата в скобки и размещение его перед преобразуемым значением — это традиционный способ, унаследованный от С:

>const double Pi = 3.14159265359;

>int x = (int) (Pi * 100);

>cout << x << " equals 314" << endl;

Это очень мощная конструкция. Она может использоваться для изменения типа указателя, устранения константности и для многого другого. Например:

>short j = 0x1234;

>if (*(char *) &j == 0x12)

> cout << "The byte order is big-endian" << endl;

В этом примере мы приводим тип short * к типу char * и используем унарный оператор * для обращения к байту по заданному адресу памяти. В системах с прямым порядком байтов этот байт содержит значение 0x12; в системах с обратным порядком байтов он имеет значение 0x34. Поскольку указатели и ссылки представляются одинаково, не удивительно, что представленный выше программный код можно переписать с приведением типа ссылки:

>short j = 0x1234;

>if ((char &) j == 0x12)

> cout << "The byte order is big-endian" << endl;

Если тип данных является именем класса, именем, введенным typedef, или элементарным типом, который может быть представлен одной буквенно—цифровой лексемой, для приведения типа можно использовать синтаксис конструктора:

>int x = int(Pi * 100);

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

• static_cast() может применяться для приведения типа указателя на А к типу указателя на В при том ограничении, что класс В должен быть наследником класса А. Например:

>A *obj = new В;

>В *b = static_cast(obj);

>b->someFunctionDeclaredInB();

Если объект не является экземпляром В (но все же наследует А), применение полученного указателя может привести к неожиданному краху программы.

• dynamic_cast() действует аналогично static_cast(), кроме применения информации о типах, получаемой на этапе выполнения (runtime type information — RTTI), для проверки принадлежности к классу В объекта, на который ссылается указатель. Если это не так, то оператор приведения типа возвратит нулевой указатель. Например:

>A *obj = new В;

>В *b = dynamic_cast(obj);

>if (b)

> b->someFunctionDeclaredInB();

В некоторых компиляторах оператор dynamic_cast() не работает через границы динамических библиотек. Он также рассчитывает на поддержку компилятором технологии RTTI, а эта поддержка может быть отключена программистом для уменьшения размера своих исполняемых модулей. Qt решает эти проблемы, обеспечивая оператор приведения


Рекомендуем почитать
Изучаем Java EE 7

Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)


Геймдизайн. Рецепты успеха лучших компьютерных игр от Super Mario и Doom до Assassin’s Creed и дальше

Что такое ГЕЙМДИЗАЙН? Это не код, графика или звук. Это не создание персонажей или раскрашивание игрового поля. Геймдизайн – это симулятор мечты, набор правил, благодаря которым игра оживает. Как создать игру, которую полюбят, от которой не смогут оторваться? Знаменитый геймдизайнер Тайнан Сильвестр на примере кейсов из самых популярных игр рассказывает как объединить эмоции и впечатления, игровую механику и мотивацию игроков. Познакомитесь с принципами дизайна, которыми пользуются ведущие студии мира! Создайте игровую механику, вызывающую эмоции и обеспечивающую разнообразие.


Обработка событий в С++

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


MFC и OpenGL

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Симуляция частичной специализации

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.