QT 4: программирование GUI на С++
Шрифт:
Определения класса
Классы определяются в С++ аналогично тому, как это делается в Java и C#, однако надо иметь в виду, что существует несколько отличий. Мы рассмотрим эти отличия на нескольких примерах. Начнем с класса, представляющего пару координат (x, у):
Представленное выше определение класса обычно оформляется в виде заголовочного файла, типичным названием которого может быть point2d.h. В этом примере проявляются следующие характерные особенности С++:
• Определение класса разделяется на секции (открытую, защищенную и закрытую) и заканчивается точкой с запятой. Если не указано ни одной секции, по умолчанию используется закрытая секция. (Для совместимости с языком С в С++ предусмотрено ключевое слово struct, идентичное классу с тем исключением, что по умолчанию используется открытая секция).
• Данный класс имеет два конструктора (один без параметров и другой с двумя параметрами). Если в классе вообще не объявляется конструктор, С++ автоматически добавляет конструктор без параметров и с пустым телом.
• Функции, получающие данные, x и y, объявляются как константные. Это значит, что они не будут (и не смогут) модифицировать переменные—члены или вызывать неконстантные функции—члены (например, setX и setY.)
Указанные выше функции реализовывались бы как встроенные функции, являющиеся частью определения класса. Альтернативный подход заключается в предоставлении в заголовочном файле только прототипов функций и реализации функций в файле .cpp. В этом случае заголовочный файл имел бы следующий вид:
Реализация
Этот файл начинается с включения заголовочного файла point2d.h, потому что прежде чем компилятор будет выполнять синтаксический анализ реализаций функций—членов, он должен иметь определение класса. Затем идут реализации функций, перед именем которых через оператор :: указывается имя класса.
Мы узнали, как можно реализовать встроенную функцию и как можно реализовать ее в файле .cpp. Семантически эти два подхода эквивалентны, однако при вызове встроенной функции большинство компиляторов просто разворачивают тело функции вместо формирования реального вызова функции. Обычно это ведет к получению более быстрого кода, но может увеличить размер приложения. По этой причине только очень короткие функции следует делать встроенными; длинные функции всегда следует реализовывать в файле .cpp. Кроме того, если мы забудем реализовать какую-нибудь функцию и попытаемся ее вызвать, компоновщик «пожалуется» на существование неразрешенного символа.
Теперь попытаемся использовать этот класс.
В С++ переменные любого типа можно объявлять без непосредственного использования оператора new. Первая переменная инициализируется с помощью стандартного конструктора Point2D (т.е. конструктора без параметров). Вторая переменная инициализируется с использованием второго конструктора. Обращение к члену объекта осуществляется с использованием оператора . (точка).