KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программирование » Жасмин Бланшет - QT 4: программирование GUI на С++

Жасмин Бланшет - QT 4: программирование GUI на С++

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Жасмин Бланшет, "QT 4: программирование GUI на С++" бесплатно, без регистрации.
Перейти на страницу:

Функции, принимающие в качестве аргументов строки С++, обычно объявляют их как char * или const char *. Ниже приводится короткая программа, иллюстрирующая оба подхода:

01 #include <cctype>

02 #include <iostream>

03 using namespace std;

04 void makeUppercase(char *str)

05 {

06 for (int i = 0; str[i] != ''; ++i)

07 str[i] = toupper(str[i]);

08 }

09 void writeLine(const char *str)

10 {

11 cout << str << endl;

12 }

13 int main(int argc, char *argv[])

14 {

15 for (int i = 1; i < argc; ++i) {

16 makeUppercase(argv[i]);

17 writeLine(argv[i]);

18 }

19 return 0;

20 }

В С++ тип char обычно занимает 8 бит. Это значит, что в массиве символов char легко можно хранить строки в кодировке ASCII, ISO 8859-1 (Latin-1) и в других 8-битовых кодировках, но нельзя хранить произвольные символы Unicode, если не прибегать к многобайтовым последовательностям. Qt предоставляет мощный класс QString, который хранит строки Unicode в виде последовательностей 16-битовых символов QChar и при их реализации использует оптимизацию неявного совмещения данных («копирование при записи»). Более подробно строки QString рассматриваются в главе 11 («Классы—контейнеры») и в главе 17 («Интернационализация»).

Перечисления

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

enum DayOfWeek {

Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday

};

Обычно это объявление располагается в заголовочном файле или даже внутри класса. Приведенное выше объявление на первый взгляд представляется эквивалентным следующим определениям констант:

const int Sunday = 0;

const int Monday = 1;

const int Tuesday = 2;

const int Wednesday = 3;

const int Thursday = 4;

const int Friday = 5;

const int Saturday = 6;

Применяя конструкцию перечисления, мы можем затем объявлять переменные или параметры типа DayOfWeek, и компилятор гарантирует возможность присваивания им только значений перечисления DayOfWeek. Например:

DayOfWeek day = Sunday;

Если нас мало волнует обеспечение защищенности типов, мы можем просто написать

int day = Sunday;

Обратите внимание на то, что при ссылке на константу Sunday из перечисления DayOfWeek мы пишем просто Sunday, а не DayOfWeek::Sunday.

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

enum DayOfWeek {

Sunday = 628,

Monday = 616,

Tuesday = 735,

Wednesday = 932,

Thursday = 852,

Friday = 607,

Saturday = 845

};

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

enum {

FirstPort = 1024, MaxPorts = 32767

};

Другой областью применения перечислений является представление набора опций. Рассмотрим пример диалогового окна Find (поиск) с четырьмя переключателями, которые управляют алгоритмом поиска (применение шаблона поиска, учет регистра, поиск в обратном направлении и повторение поиска с начала документа). Это можно представить в виде перечисления, значения констант которого равны некоторой степени 2:

enum FindOption {

NoOptions = 0x00000000,

WildcardSyntax = 0x00000001,

CaseSensitive = 0x00000002,

SearchBackward = 0x00000004,

WrapAround = 0x00000008

};

Каждая опция часто называется «флажком». Флажки можно объединять при помощи логических поразрядных операторов | или |=:

int options = NoOptions;

if (wilcardSyntaxCheckBox->isChecked())

options |= WildcardSyntax;

if (caseSensitiveCheckBox->isChecked())

options |= CaseSensitive;

if (searchBackwardCheckBox->isChecked())

options |= SearchBackwardSyntax;

if (wrapAroundCheckBox->isChecked())

options |= WrapAround;

Проверить значение флажка можно при помощи логического поразрядного оператора &:

if (options & CaseSensitive) {

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

}

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

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

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

typedef QVector<Point2D> PointVector;

После этого можно использовать имя 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.

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

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

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);

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

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*