Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Прикладное программирование на CC++ с нуля до мультимедийных и сетевых приложений
.pdf
Техника работы в С++ Builder 61
пасть в место текста, где находится функция-обработчик, достаточно во время
работы с проектом сделать двойной щелчок по кнопке.
Внутри фигурных скобок в функции-обработчике можно запрограммировать любые действия, которые приложение должно выполнить при нажатии
на управляющую кнопку. Мы хотим, чтобы наша программа поздоровалась с
окружающим миром при щелчке на кнопке. Самый простой способ — вывести нужный текст в специальное окно сообщений. Поместим между фигурными скобками слово ShowMessage. Что это такое? Это — некая новая конструкция, о которой мы пока ничего не знаем. Самое время воспользоваться системой помощи, которую предоставляет нам Builder. Для вызова справки по
любому служебному слову в программе достаточно установить курсор ввода в
любое место на этом слове и нажать клавишу F1 на клавиатуре. Проделав эту
операцию над словом ShowMessage, мы откроем окно помощи, представленное на рис. 2.2.
Ðèñ. 2.2
В краткой аннотации мы читаем, что конструкция предназначена для вывода в окно сообщений текста и кнопки ÎÊ. Более подробная информация
представлена в нижней части окна, а формальное объявление — в средней.
Особенно вглядываться в формальное объявление не стоит. Нам нужно только установить, что после имени конструкции в круглых скобках должна стоять строка типа AnsiString. Этот тип — пример множества новых типов данных, появившихся в языке С++ в дополнение к стандартным типам языка С.
Заметим попутно, что многие имена типов в С++ просто являются псевдонимами стандартных имен С. На самом деле часто это даже и не типы языка
С++, а типы системы программирования WINDOWS — так называемой сис
-

62 Глава 2. Объектно-ориентированное программирование
òåìû API. Например, тип UINT — это не что иное, как обычное unsigned int.
В нашем случае тип AnsiString мало чем отличается от обычного строкового
типа. В этом можно убедиться, открыв ссылку Example в окне помощи и просмотрев пример использования конструкции. В результате мы придем к выводу о том, что в скобках должна быть помещена обычная строка текста, взятая
в кавычки. Именно этот текст и будет отображен в окне сообщений.
Вернемся к нашему главному текстовому модулю и допишем в фигурных
скобках то, что требуется, допустив сознательно синтаксическую ошибку:
ShowMessage("Hello World!);
Ошибка заключается в том, что мы «забыли» закрыть кавычки справа.
А сделали мы это для того, чтобы продемонстрировать реакцию системы на
ошибку в программе. Давайте нажмем заветную кнопку F9. На этапе компиляции система начнет «ругаться» и в результате выдаст окно, представленное
на рис. 2.3.
Ðèñ. 2.3
В верхней части окна отображена часть текстового модуля с выделенной
строкой, в которой обнаружена ошибка. В нижней части окна дана расшифровка ошибок. Обратите внимания на то, что компилятор ухитрился найти
три ошибки, хотя на самом деле ошибка только одна — первая. Остальные
ошибки называют наведенными. Из этого следует правило: сначала исправьте
первую ошибку и, возможно, остальные исчезнут.
Итак, в качестве первой ошибки компилятор констатирует наличие незавершенной строки или символьной константы, и мы знаем, что компилятор в

Техника работы в С++ Builder 63
данном случае прав. Вторая ошибка заключается в отсутствии закрывающей
скобки при вызове функции, и это, мягко говоря, не соответствует действительности. То же самое следует сказать и о третьей ошибке — отсутствии символа «;» в выражении. Наведенные ошибки!
Исправим ошибку, поставим в нужном месте закрывающие кавычки. Теперь и компиляция, и линковка, и запуск программы должны пройти без осложнений. В результате откроется окно созданной программы с кнопкой
Button1. Когда вы щелкнете по кнопке мышью, появится окно сообщений с
приветствием и кнопкой ÎÊ, показанное на рис. 2.4.
Ðèñ. 2.4
Совершенно очевидно, что все, что теперь можно сделать в программе,
это нажать кнопку ÎÊ, и окно сообщений закроется. Далее остается только
закрыть окно программы и поздравить себя с первым «самодельным» приложением.
Как мы с вами поняли, по умолчанию Builder создает проект для приложения, базирующегося на использовании формы. В ряде случаев использование формы не является необходимым, а иногда и нежелательно. Рассмотрим
разработку приложения без формы и, следовательно, без организации окна
приложения.
Прежде всего, необходимо с помощью любого текстового редактора написать текст, представленный в следующем листинге. Текст следует сохранить в
рабочей папке будущего проекта под именем, например, Unit1.cpp.
#include <windows.h>
int PASCAL
WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpszCmdLine,
int nCmdShow)

64 Глава 2. Объектно-ориентированное программирование
{
MessageBox(NULL,"Привет","Без окна",MB_OK);
return 0;
}
В любом файловом менеджере или проводнике Window перейдите в папку
и сделайте двойной щелчок мышью по этому файлу. Предполагается, что
файлы с расширением .ñðð связаны с Builder'îì. Builder загрузит файл и предложит создать проект для приложения, с чем следует согласиться. Далее
обычным образом клавишей F9 нужно запустить обработку проекта — компиляцию, линковку и запуск. В результате будет создан и выполнен исполняемый файл программы, и на экране вы увидите то, что показано на рис. 2.5.
Ðèñ. 2.5
Что же мы здесь имеем? Обратимся к листингу. Прежде всего, отметим,
что для всех приложений Windows, а именно с такими программами мы и работаем, практически всегда требуется подключение заголовочного файла
windows.h. Далее, если мы не используем форму, то есть отходим от
Builder-проекта по умолчанию, то необходимо использовать главную функ-
öèþ WinMain. Это — аналог функции main в языке С. С нее начинается выполнение программы, а у нас она вообще единственная. В наши задачи пока
не входит подробно знакомить читателя с синтаксисом тех или иных конструкций языка. Поэтому примите оформление функции WinMain в листинге в
качестве «истины в последней инстанции», а если это вас не устраивает (и
это прекрасно!), то читайте документацию. Укажем только, что функция имеет целый тип и, поэтому, последним выражением имеет оператор возврата
return 0, хотя это возвращаемое значение нигде не используется.
Внутри функции WinMain мы вольны делать все, что нам захочется. А захотелось нам создать приветствие, но немного отличающееся от приветствия
в первой программе. Для этой цели мы использовали функцию MessageBox.
Если вы посмотрите в справку по этой функции, то увидите, что первым аргументом у нее должен быть указатель порождающего окна, а поскольку у нас
такового нет, мы и поставили здесь NULL. Второй аргумент — текст, выводимый в окно сообщения. Здесь все ясно. Третий аргумент — текст в заголовке
окна, что также не требует пояснений. Последний аргумент содержит системную константу, определяющую, что еще будет в окне. В данном случае в окне
будет еще кнопка ÎÊ, которая закрывает как само окно сообщения, так и всю
программу.
Большинство приложений, создаваемых в Builder'е, могут иметь в своей
основе окно, задаваемое формой так, что именно такая конфигурация нового

Техника работы в С++ Builder 65
создаваемого проекта предлагается по умолчанию. Огромное упрощение разработки программ достигается с помощью размещения на форме так называемых визуальных компонентов (VC), уже упомянутых и использованных в первой программе. Несомненно, и мы в дальнейшем будем использовать визуальные компоненты в нашей работе, в связи с чем необходимо поговорить об
этих инструментах более подробно.
По сути дела VC являются объектами специализированных классов, инкапсулирующих в себе свойства (properties) и методы (methods). Кроме того, к
членам классов визуальных компонентов следует отнести так называемые события (events) — «происшествия», случающиеся с VC. Главной особенностью
этих специальных классов является то, что объекты VC обычно отображаются
в окне формы в виде разнообразных визуальных конструкций: кнопок, полей
ввода данных, полей выбора и многих других «картинок», которые мы видим
при работе готовых программ в Windows. Как это ни парадоксально звучит, но
существуют и не визуальные VC. Эти объекты не отображаются в окнах работающих программ, а используются именно при разработке приложений. Вот
со всеми этими премудростями нам сейчас и предстоит вкратце познакомиться. По-прежнему не будем излагать материал последовательно и скрупулезно,
а проиллюстрируем все необходимое примерами.
Поставим себе следующую задачу. Необходимо разработать программу,
которая при запуске открывает окно, представленное на рис. 2.6.
Ðèñ. 2.6
Здесь имеются две надписи, поле ввода числового значения и одна кнопка. В открывшемся окне мы должны иметь возможность изменить или оставить предложенным по умолчанию число. После нажатия кнопки ÎÊ программа должна просто завершить свою работу, закрыть окно по истечении
времени, указанного в поле ввода.
Создадим новый проект с формой, а это мы уже умеем делать, предварительно подготовив папку для проекта. Сохраните пока пустой проект. Поместите на форму визуальный компонент Label (метка) со вкладки Standard библиотеки VCL. Этот компонент обозначен большой буквой À. Как только вы
положили VC на форму, он отобразится в окне инспектора объектов (Object
Inspector) слева от формы. Здесь будет открыта вкладка свойств объекта
Properties. Â ïîëå Caption сейчас написано Label1. Замените надпись на ÇÀ-

66 Глава 2. Объектно-ориентированное программирование
КРЫТЬ ПРОГРАММУ ЧЕРЕЗ. Текст в метке на форме соответственно изменится. Метку можно перемещать по форме, захватив ее мышью. Передвиньте
компонент ближе к верхнему левому углу. Если после этого метка перестала
отображаться в инспекторе (и там стала отображаться форма), просто снова
щелкните по ней мышкой. Активизируйте свойство Color и по стрелке справа
выберите цвет фона. Мы сделали его белым. Поместите правее метки компонент Edit с той же вкладки Standard. Свойство Text замените на 5000. Правее
только что созданного поля редактирования поместите еще одну метку с текстом МИЛЛИСЕКУНД и тоже белым фоном. На этом этапе можно проверить, все ли у нас в порядке. Сохраните проект и запустите его на исполнение. У вас должно появиться окно с отображением созданных элементов. Закройте его.
Со вкладки System библиотеки визуальных компонентов возьмите таймер
(Timer) и разместите его на форме. Таймер работает следующим образом. Как
только он становится доступным, то есть как только его свойство Enable становится ИСТИНОЙ (true), начинается отсчет времени. После того как пройдет столько миллисекунд, сколько задано в свойстве таймера Interval, наступает событие OnTimer, реакцию на которое нужно запрограммировать. Таким
образом, установите свойство таймера на вкладке Properties инспектора объектов в false (ЛОЖЬ) — сначала таймер должен быть заблокирован. Перейдите
на вкладку событий (events) и сделайте двойной щелчок мышью по пустому
полю правее названия события OnTimer. Сразу же откроется главный текстовый модуль программы, где тут же сформируется функция — обработчик события. Тело функции пока пусто. Здесь мы должны написать выражение, задающее реакцию на событие. Реакция очень проста — закрыть программу.
Для этого можно, например, вызвать функцию exit(1). Теперь обработчик события в текстовом модуле должен выглядеть следующим образом:
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
exit(1);
}
На следующем этапе разместим на форме кнопку, изменив название
(свойство Name) с установленного по умолчанию Button1 íà ÎÊ — â ïîëå
Name напишите ÎÊ и нажмите Enter. Теперь необходимо написать обработчик события OnClick щелчка по кнопке. Это, конечно, можно сделать через
инспектор объектов, но для основного события объекта, а для кнопки щелчок — это основное событие, можно поступить проще. Сделайте двойной
щелчок по кнопке на форме, и вы сразу попадете в текстовый модуль, в
функцию-обработчик, которая тоже пока пуста.
Что необходимо написать в обработчике? Сначала нужно задать интервал
срабатываний таймера. Этот интервал, выраженный в миллисекундах, необходимо взять из поля редактирования и присвоить соответствующему параметру
таймера. Напомним, что параметр Interval является свойством объекта Timer1,
а текст в поле редактирования является свойством Text объекта Edit1. Казалось
бы, что для достижения поставленной цели нужно применить выражение при
-

Структуры 67
сваивания Timer1->Interval = Edit1->Text;. Если мы вставим это выражение в
обработчик и попробуем скомпилировать программу, то получим ошибку:
[C++ Error] Unit1.cpp(26): E2034 Cannot convert 'AnsiString' to 'unsigned int'.
Компилятор сообщает вам, что не может превратить выражение типа
строка в выражение типа беззнаковое целое. Действительно, если вы обратитесь к справке по конструкции Interval для таймера и конструкции Text для
поля редактирования, то увидите, что эти величины разного типа. Дело поправимое. Для конвертирования строки в целое существует специальная
функция StrToInt, и если в обработчике написать
Timer1->Interval = StrToInt(Edit1->Text);
то все будет в порядке.
Далее в обработчике щелчка по кнопке следует запустить таймер — присвоить свойству Enabled значение ИСТИНА (true). Окончательно функция-обработчик должна выглядеть следующим образом:
void __fastcall TForm1::OKClick(TObject *Sender)
{
Timer1->Interval = StrToInt(Edit1->Text);
Timer1->Enabled = true;
}
Теперь все готово к запуску программы. Сделаем это. Возможно, не лишним будет отметить, что после запуска приложения в поле редактирования
значение 5000 миллисекунд, заданное нами по умолчанию, можно заменить
на любое другое.
На этом изготовление программы заканчивается. Можно немного «навести красоту». Захватив мышкой рамку формы слева или справа, снизу или
сверху, можно изменить размеры окна формы и привести их к виду, показанному на рисунке. Вместо безликого form1 можно задать имя окна формы через свойство Caption в инспекторе объектов. Наконец отметим, что таймер является тем самым не визуальным VCL-компонентом. При разработке он присутствует на форме, при исполнении программы он не виден.
Структуры
Для объединения однотипных данных (именно переменных заданного
типа) в языке С используются массивы. Существует средство объединения
по какому-то признаку и элементов различных типов. Такие средства получили название структур. Вообще говоря, без использования структур в большинстве программ можно было бы безболезненно обойтись. Однако при переходе к языку С++ знакомство со структурами становится крайне желательным, поскольку от понятия структуры можно наиболее естественным
образом перейти к фундаментальному понятию объектно-ориентированного

68 Глава 2. Объектно-ориентированное программирование
программирования — понятию класса. Кроме того, в практике программирования структуры используются на удивление широко. Типичный пример:
программирование записи, обработки и воспроизведения звука и изображений средствами Windows практически полностью основывается на использовании структур.
Формальное описание структуры как типа данных имеет следующий
вид:
struct [Òåã]
{
Объявления элементов структуры;
} [Переменные структуры];
Служебное слово struct означает, что объявлена структура. Необязательная (в связи с этим взятая в прямые скобки) конструкция Òåã является именем типа структуры. При декларации в программе конкретной переменной
структуры Òåã будет выступать в роли имени типа (как int, long и прочее).
В фигурных скобках помещаются описания членов структуры, называемых
также элементами и полями. Описания полностью совпадают с описаниями
переменных в программе, например, double s; int a[12]; char *sss и так далее.
Само по себе объявление типа структуры не создает соответствующих переменных. Введение в программу переменной структуры может быть выполнено двумя способами. Во-первых, переменную можно объявить стандартным
образом. Пусть описан тип структуры:
struct NewStr
{
int a,b;
double c;
};
Тогда в функции, работающей с данной структурой, может быть задана
следующая конструкция:
NewStr A,*B,C[4];
Здесь описана переменная структуры À, указатель на переменную структуры B и массив из четырех переменных структуры Ñ описанного типа.
Во-вторых, объявление переменных структуры можно сделать сразу при
декларации типа структуры. В этом случае та же конструкция A,*B,C[4] помещается после закрывающей фигурной скобки. При этом тег структуры задавать не обязательно.
Обращение к членам структуры в программе выполняется с помощью
разделителя «.» (точка) или разделителя «->» (стрелка). Если обращение выполняется через имя переменной структуры, то используется первый вариант.
Так, в нашем примере для присвоения значения члену b числового значения
можно применить выражение присваивания:
A.b = 7;

Структуры 69
Поскольку у нас объявлен указатель на структуру Â, аналогичное выражение присваивания будет выглядеть так:
B->b=7;
Теперь рассмотрим небольшой пример, типичный для работы со структурами. Определим структуру, в которой будут содержаться данные на десятерых сотрудников отдела некоторой организации. Данные представляют собой
порядковый номер сотрудника — целое значение num, фамилия, записанная
в строке — символьный массив name, возраст — целая переменная age,
пол — символьный массив из одного элемента sex, в который заносится буква f èëè m. Очевидно, все перечисленные элементы в свою очередь являются
элементами массивов длиной 10 по числу сотрудников.
#include <stdio.h>
#include <conio.h>
#include <string.h>
struct BASE {
int num[10];
char name[10][24];
int age[10];
char sex[10][1];
};
void main(void)
{
BASE bas1,bas2; int i;
FILE *f1;
clrscr();
bas1.num[0]=0;
strcpy(bas1.name[0],"Ivanov");
bas1.age[0]=44;
strcpy(bas1.sex[0],"m");
f1=fopen("C:\ivb\ppis\bas1f.txt","wb");
fwrite(&bas1,sizeof(bas1),1,f1);
fclose(f1);
f1=fopen("C:\ivb\ppis\bas1f.txt","rb");
fread(&bas2,sizeof(bas1),1,f1);
puts(bas1.name[0]);
fclose(f1);
getch();
}
В приведенном листинге объявлен тип структуры BASE и в главной функции созданы два экземпляра структуры bas1 è bas2. В программе инициализируются поля для первого (точнее — нулевого) сотрудника с номером 0, фамилией Ivanov, возраст 44 года, пол мужской. Остальные девять «строк» в структуре остаются не инициализированными. По некоторому пути в файловой
системе открывается для записи двоичный файл с именем bas1f.txt. Расширение txt не должно вводить читателя в заблуждение. Мода «wb» функции от
-

70 Глава 2. Объектно-ориентированное программирование
крытия файла fopen определяет то, что файл именно двоичный и открыт для
записи. Нетрудно видеть, что в указанный дисковый файл целиком копируется структура bas1. Далее файл закрывается и вновь открывается уже для чтения. Содержимое файла копируется в экземпляр структуры bas2, и из этой
структуры извлекается и выводится на экран фамилия пользователя. При правильной работе программы должно быть напечатано, естественно, слово
Ivanov. Наверное, нет нужды подробно пояснять, что здесь представлена «заготовка» работы со структурой в форме некоторой базы данных — ее создание, изменение и сохранение на диске в виде файла.
Классы
Понятие класса является ключевым и основополагающим понятием объектно-ориентированного программирования (ООП). С другой стороны, это
понятие является логическим продолжением и расширением понятия структуры, с которым оперируют и не объектно-ориентированные системы. Также
как и структуру, класс с полным основанием можно рассматривать как новый
тип данных. Переменные такого типа как раз и являются теми самыми объектами, которые и дали название ООП.
Переход от структуры к классу, как расширение структуры, в первую очередь связано с возможностью включения в класс кроме переменных-членов
еще и функций-членов. В современной литературе по ООП принято называть
функции-члены методами класса, а переменные-члены — свойствами класса.
Вторым важнейшим отличием от структуры является то, что члены класса
(как переменные, так и функции) могут быть либо открытыми, либо закрытыми. По умолчанию все члены класса являются закрытыми. Это означает то,
что оперировать с закрытыми данными могут только собственные методы
класса. Если же необходимо получить доступ к свойствам извне (например, из
главной функции программы), то свойства должны быть объявлены открытыми с помощью ключевого слова public:. Разумеется, для обеспечения возможности вызова функций-членов извне необходимо эти методы также объявить
открытыми.
В простейшем виде синтаксис объявления класса может выглядеть следующим образом:
class имя-класса
{
// Объявления закрытых членов класса
public:
// Объявления открытых членов класса
}[Объекты] ;
Формально имя класса может быть опущено, аналогично тегу структуры.
На практике же имя задается практически всегда. Также, аналогично структурам, после закрывающей фигурной скобки может быть сформирован список
объектов класса — по именам или указателям. При этом сразу при объявле-
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
