Content-Type: multipart/related; start=<op.mhtml.1332566463516.1078f7233814420b@192.168.2.2>; boundary=----------wOCwWjjIy35ybHEPCvEFB0
Content-Location: http://www.piter-press.ru/attachment.php?barcode=978580460053&at=exc&n=0
Subject: =?utf-8?Q?Visual=20C++=206.=20=D0=A3=D1=87=D0=B5=D0=B1=D0=BD=D1=8B=D0=B9=20=D0=BA=D1=83=D1=80=D1=81=20(=D1=81=D1=82=D0=B0=D1=80=D0=B0=D1=8F=20=D0=BE=D0=B1=D0=BB)?=
MIME-Version: 1.0

------------wOCwWjjIy35ybHEPCvEFB0
Content-Disposition: inline; filename=attachment.htm
Content-Type: text/html; charset=windows-1251; name=attachment.htm
Content-ID: <op.mhtml.1332566463516.1078f7233814420b@192.168.2.2>
Content-Location: http://www.piter-press.ru/attachment.php?barcode=978580460053&at=exc&n=0
Content-Transfer-Encoding: 8bit


			<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
			"http://www.w3.org/TR/html4/loose.dtd">
				<html>
					<head>
						<title>Visual C++ 6. Учебный курс (старая обл)</title>
						<link rel="SHORTCUT ICON" href="http://shop.piter.com/piter.ico">
						<META  name="keywords" content=" книга, издательство, издательский дом, книги почтой, купить книгу, заказ книг, интернет магазин, интернет библиотека, скачать книгу, литература, библиотека, Санкт-Петербург, Питер, Петербург, продажа, торговля, книги по компьютерам, заказ, магазин, электронная коммерция, компьютерная литература, новинка, бестселлер, компьютеры, интернет, программы, софт, книги по медицине, книги по психологии, книги по экономике, книги по маркетингу, книги по финансам, книги по менеджменту, book, publishing, webshop,web, internet, computer, Peterburg, russia, soft, shop, e-shop, ecommerce, ebusiness, psychology, economy, education, medicine, crime, investigation, bestseller">
						<META name="robots" content="ALL">
						<META  name="description" content="Книги для профессионалов и новичков от Издательского дома &quot;Питер&quot;. Работает электронный магазин, доставка по всему миру, скидки для постоянных читателей. Do you need a nice book for your work? Welcome! We reside in St.-Petersburg (Russia). Webshop is opened 24h.">
						<META HTTP-EQUIV="Expires" CONTENT="0">
						<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
						<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
						<meta http-equiv="Cache-Control" Content="0">
						<meta name="Other.Language" content="Russian">
						<link href="/main.css?a=111" rel="stylesheet" type="text/css">
						<script type="text/javascript" src="/js/common_utils.js?b=111"></script>
						<script type="text/javascript" src="/engine.js?b=111"></script>
					</head>
					<body><table><td>
						<h4><a href="/book.phtml?978580460053">Visual C++ 6. Учебный курс (старая обл)</a></h4>
						<a href="/publish/authors/19208/0/">Холзнер С.</a>
						<br><br><br>
						<p class= medium><font size=2>



<font size=+1><a href="#27"><b>Урок 1.</b> Первое знакомство с C++</a></font>



<b><a href="#1"><dl><dt>Обзор Visual C++<br></a>	

<a href="#2"><dt>Наша первая программа</a></b>



<a href="#3"><dd>Рабочие области и проекты Visual C++</a>

<a href="#4"><dd>Создание файла с исходным текстом</a>

<a href="#5"><dd>Добавление кода на C++</a>

<a href="#6"><dd>Что такое потоки C++?</a>

<a href="#7"><dd>Запуск первой программы</a>



<b><dt><a href="#8">Классы и объекты C++</a></b>



<a href="#9"><dd>Что такое объект?</a>

<a href="#10"><dd>Что такое класс?</a>



<b><dt><a href="#11">Наша первая программа на C++ с классами и объектами</a></b>



<a href="#12"><dd>Что такое модификатор доступа?</a>

<a href="#13"><dd>Инициализация данных класса в конструкторе</a>

<a href="#14"><dd>Использование класса DataClass</a>



<b><dt><a href="#15">Реальный пример на C++</a></b>



<dd><a href="#16">Деструкторы C++</a>



<b><dt><a href="#17">Сохранение, извлечение и обработка данных</a></b>



<a href="#18"><dd>Сохранение данных методом AddScore()</a>

<a href="#19"><dd>Извлечение данных методом GetScore()</a>

<a href="#20"><dd>Вычисление средней оценки методом AverageScore()</a>

<a href="#21"><dd>Использование класса SchoolClass в программе</a>



<b><dt><a href="#22">Что такое наследование и переопределение?</a></b>



<a href="#23"><dd>Создание производного класса</a>

<a href="#24"><dd>Изменение метода - переопределение</a>



<b><dt><a href="#25">Перегрузка функций в C++</a>

<dt><a href="#26">Что нового мы узнали?</a></b>

</dl>









<a name="27"><p>Добро пожаловать в мир Visual C++! Visual C++ - это инструмент для программирования в среде Windows, обладающий поистине фантастическими возможностями. Более того, многие разработчики считают Visual C++ самой мощной из всех программ такого класса. На самом деле Visual C++ представляет собой целый набор из множества инструментов, собранных в одном динамичном пакете, готовом к немедленной работе.</a>

<p>В этой книге мы изучим эти инструменты и посмотрим, как с их помощью решаются самые различные задачи по созданию профессиональных программ для Windows - от вывода графики до построения меню, от кнопок и текстовых полей до работы с файлами, от подключения к Интернету до разработки собственных элементов ActiveX. Среди прочего мы создадим настоящий Web-броузер, работающий с гиперссылками и графикой, а также текстовый редактор с возможностями копирования/вставки, печати, сохранения текста на диске, переноса строки и множеством других функций. Мы напишем графический редактор, в котором можно будет рисовать геометрические фигуры, "растягивая" их мышью, заполнять их фоновой заливкой, сохранять на диске и т. д. Об этом и о многом другом речь пойдет позже, а начнется все с этого урока.

<p>Книга посвящена трем основным темам: собственно программированию на C++ (использованию классов, объектов и другим приемам объектно-ориентированного программирования); Visual C++ (и главным образом его внутренним ресурсам, объединенным в библиотеку Microsoft Foundation Classes, или MFC); и программированию для Windows (основным принципам работы Windows-приложений, созданию меню, кнопок и т. д.). В этом уроке мы рассмотрим некоторые базовые понятия программирования на C++: классы, объекты, переопределение функций и т. д.

<p>Для простоты наши первые программы не будут создавать собственные окна, вместо этого они будут пользоваться окнами, которые за них создает Visual C++. На примере этих программ мы научимся работать с Visual C++ и узнаем все необходимое для дальнейшего изучения. В следующем уроке мы научимся создавать окна и управлять ими в среде Windows с помощью Visual C++. Первый урок начинается с краткого обзора пакета, с которым нам предстоит работать.



<dir><hr>Если вы знакомы с такими концепциями C++, как наследование, переопределение, перегрузка, классы и объекты, можете переходить ко второму уроку и приступать к программам, которые создают окна и управляют ими. Если же вы впервые встречаетесь с этими понятиями, пожалуйста, изучите этот урок - нам понадобится прочный фундамент для построения программ в последующих главах. Предполагается, что у вас уже есть небольшой опыт программирования, например, вы понимаете, что такое переменные и функции. Если же вы вообще ничего не знаете о программировании, то перед тем, как продолжать, потратьте немного времени на знакомство с переменными и функциями.<hr></dir>



<a name="1"><h3>Обзор Visual C++</h3></a>



<p>Если вам приходилось заниматься программированием для Windows до появления Visual C++, вероятно, оно оставило у вас не самые лучшие воспоминания. Сначала программы для Windows приходилось писать на языке C, а не на C++, и получались они большими и сложными. Многие "официальные" приемы, которые использовались в те времена, выглядели очень плохо - например, всего один оператор (switch-оператор языка C) растягивался на несколько страниц. Даже вывод на экран пустого окна требовал примерно пяти страниц сложного и невразумительного кода.

<p>Теперь все изменилось. Появился язык C++, идеально подходящий для Windows-программирования. Как мы вскоре убедимся, он позволяет хранить большую часть программного кода внутри самостоятельных объектов, а это сокращает объем больших программ (изначально C++ был разработан именно для того, чтобы облегчить работу с большими программами). Программировать для Windows стало значительно проще, а на смену "плохой" технике программирования пришла "хорошая". Кроме того, программы на C++ стало значительно проще отлаживать. Вместо одной огромной монолитной программы мы имеем дело с набором аккуратных и удобных в обращении частей.

<p>Помимо этого, фирма Microsoft разработала библиотеку Microsoft Foundation Classes, и хотя это может показаться неожиданным, в программировании для Windows эта библиотека сыграла не менее важную роль, чем язык C++. MFC - замечательный пакет, состоящий из заранее написанного и готового к работе кода. Например, вместо того чтобы самостоятельно писать программу для работы с новым окном (что требует немалых усилий), можно просто воспользоваться классом CWnd из MFC, который выполнит всю работу за вас. Пользуясь стандартными приемами C++, о которых пойдет речь в этом уроке, вы сможете настроить компоненты MFC (такие, как класс CWnd) в соответствии со своими требованиями, например изменить текст в заголовке окна.

<p>Visual C++ не только использует MFC, но и значительно облегчает программирование для Windows благодаря наличию многих вспомогательных инструментов, например, редактора меню или специального редактора для графического проектирования диалоговых окон. Visual C++ предоставляет интегрированную среду разработки, в которой можно писать и запускать программы. Кроме того, все файлы, составляющие программу для Windows, в Visual C++ организуются в виде проектов. Скоро мы увидим, что это существенно облегчает нашу задачу. На самом деле мастера (специальные программные инструменты) Visual C++ могут написать за нас немалую часть программы, но ими мы займемся в следующем уроке.

<p>Для начала хватит и краткого обзора Visual C++. Пора приступать к делу и учиться работать с этим мощным и многофункциональным пакетом.

<p>В первом уроке мы воспользуемся Visual C++ отнюдь не для создания программ с собственными окнами. Напротив, мы по возможности упростим ситуацию, чтобы не загромождать примеры программ на C++ многочисленными ненужными деталями. Изучать базовые понятия языка C++ на примере программы с собственным окном было бы слишком сложно, а мы будем осваивать программирование на Visual C++ постепенно.

<p>В оставшейся части этого урока мы рассмотрим основы C++ и поручим Visual C++ все хлопоты по созданию окон для наших программ и работе с ними. О том, как работать с окнами в среде Windows, речь пойдет в следующем уроке.



<a name="2"><h3>Наша первая программа</h3></a>



<p>Программы на Visual C++ как-то быстро и незаметно усложняются и увеличиваются в размерах. При изучении таких программных концепций C++, как классы и объекты, мы постараемся сохранить максимальную простоту.

<p>Некоторые программисты даже не знают, что Visual C++ можно использовать и для создания консольных приложений. Именно этим мы сейчас и займемся. Такие программы работают в окнах, напоминающих окна сеансов DOS. Наш первый пример будет чрезвычайно простым: мы просто выведем на экран сообщение: "Welcome to C++", то есть "Добро пожаловать в C++!"1.

<p>Посмотрим, как это делается. Запустите Visual C++ - на экране появится окно, изображенное на рис. 1.1.

<p>Программы на Visual C++, которые мы будем писать в этой книге, как правило, будут иметь собственные окна, но только не в этом уроке. Здесь мы займемся созданием консольных программ Win32 - для них окно предоставляет Visual C++. Поскольку сейчас нас интересует только программирование на C++, этого вполне достаточно.



<center><img src="/contents/978580460053/1-1.gif"><br><b>Рис. 1.1.</b> Среда Visual C++</center>





<a name="3"><h3>Рабочие области и проекты Visual C++</h3></a>



<p>Наша первая программа будет называться first, и мы создадим ее как новый проект Visual C++. Программные задачи в Visual C++ оформляются в виде проектов; обычно для каждой отдельной программы создается свой проект. Проект (project) представляет собой набор файлов, которые совместно используются для создания одной программы.

<p>Кроме того, сами проекты размещаются в рабочих областях (workspaces), причем одна рабочая область может содержать несколько проектов (активный проект задается в Visual C++ командой Project д Set Active Project). Все проекты, созданные нами, будут иметь собственные рабочие области, однако в этой книге нам почти не придется заниматься рабочими областями: Visual C++ автоматически создает их для каждого нового проекта, поэтому в первую очередь нас будут интересовать проекты, а не рабочие области. Все же необходимо помнить о том, что вы работаете в рабочей области Visual C++, а проект принадлежит ей.

<p>Давайте создадим и запустим первый проект:



<ol><li>Выполните команду File - New в Visual C++; на экране появляется окно New (рис. 1.2).

<li>Перейдите на вкладку Projects и выберите из списка строку Win32 Console Application.

<li>Введите в текстовом поле Project name имя проекта first, а в поле Location укажите каталог для проекта. В наших примерах используется каталог C:\VCPP, поэтому в поле Location следует ввести строку C:\VCPP\FIRST1.

</ol>

<center><img src="/contents/978580460053/1-2.gif"><br><b>Рис. 1.2.</b> Создание нового проекта в Visual C++</center>

<ol type=1 start=4>

<p><li>Нажмите кнопку OK в диалоговом окне New. На экране появляется новое диалоговое окно с именем Win32 Application.

<li>Нажмите кнопку Finish - Visual C++ создаcт новую программу с именем first. В нее входят два важных файла: first.dsw определяет параметры новой рабочей области, а first.dsp - параметры нового проекта.</ol>



<dir><hr>Чтобы продолжить работу над программой, над которой вы трудились раньше, воспользуйтесь командой Visual C++ File д Open Workspaces... и откройте файл рабочей области программы (с расширением .dsw).<hr></dir>



<p>Итак, мы создали новую рабочую область, а в ней - проект с именем first. Теперь нужно ввести исходный текст программы; нам нужно, чтобы программа выводила строку "Welcome to C++".



<a name="4"><h3>Создание файла с исходным текстом</h3></a>



<p>Для текста программы нам понадобится новый файл first.cpp. Расширение .cpp присваивается файлам с текстами программ на C++.



<dir><hr>Помимо файлов с исходными текстами в программах на C++ часто встречаются заголовочные файлы с расширением .h. Как мы увидим в следующем уроке, заголовочные файлы содержат объявления переменных и функций.<hr></dir>



<p>Давайте создадим файл first.cpp и включим его в проект:



<ol><li>Снова выполните команду File д New, только на этот раз перейдите на вкладку Files (рис. 1.3).

<li>Выберите из списка строку C++ Source File и введите имя файла first.cpp в текстовом поле File namе.

<li>Проследите, чтобы флажок Add to project был установлен (см. рис. 1.3). Нажмите кнопку OK.

<li>Файл first.cpp создается и открывается в среде Visual C++, как показано на рис. 1.4.</ol>



<p>Среда Visual C++ состоит из трех основных окон: слева расположено окно просмотра с корешками вкладок в нижней части (ClassView и FileView). Справа от него находится окно редактора, в котором происходит редактирование документов (в настоящий момент в нем открыт пустой файл first.cpp). Внизу расположено окно результатов со вкладками Build, Debug и Find in Files.



<center><img src="/contents/978580460053/1-3.gif"><br><b>Рис. 1.3.</b> Создание нового файла с исходным текстом программы в Visual C++</center>



<p>В окне просмотра выводится общая структура проекта, но ее конкретное представление зависит от выбранной вкладки - ClassView или FileView (о других вкладках мы поговорим позже). На вкладке ClassView показана иерархия классов C++ в рабочей области; вскоре мы узнаем, что такое классы. На вкладке FileView показана иерархия файлов в рабочей области (на рис. 1.4 она состоит из рабочей области, проекта и файла first.cpp).



<dir><hr>В следующем уроке, когда мы начнем работать с полноценными программами на Visual C++, в окне просмотра появится еще одна вкладка - Resources. Такие объекты как меню, диалоговые окна и панели инструментов, в программировании для Windows являются ресурсами.<hr></dir>



<p>В окне редактирования отображаются открытые документы. Обычно в нем работает текстовый и другие редакторы, например, редактор меню или диалоговых окон.



<center><img src="/contents/978580460053/1-4.gif"><br><b>Рис. 1.4.</b> Новый файл, открытый в Visual C++</center>





<p>В окне результатов в нижней части рис. 1.4 выводится информация о ходе компиляции программ (так называется процесс их преобразования в двоичный код, с которым может работать компьютер). Кроме того, это окно используется для отладки и других целей, о которых будет рассказано далее.



<a name="5"><h3>Добавление кода на C++</h3></a>



<p>Теперь мы добавим программный код в файл first.cpp, который в настоящий момент открыт в окне редактирования Visual C++. Чтобы создать свою первую программу на C++, введите следующий текст:<br>

#include &lt;iostream.h&gt;<br><br>



void main()<br>

{

    cout &lt;&lt; &quot;Welcome to C++ \n&quot;;<br>

}



<p>Так выглядит наша первая программа. В ней мы воспользовались стандартными средствами C++ для вывода текстовой строки, в нашем случае - "Welcome to C++".

<p>Сначала мы включаем (#include) в программу файл iostream.h. Это позволит нам работать со стандартными средствами экранного вывода C++ (содержимое включенного файла просто вставляется в исходный текст программы).

<p>Затем мы определяем функцию с именем main(). Эта функция вызывается при запуске программы. Другими словами, когда вы запускаете файл (например, first.exe), Windows ищет в нем функцию main() и выполняет содержащийся в ней код; поэтому мы и включили в нее тот код, который необходимо выполнить. Вскоре мы рассмотрим функцию main() более подробно.



<dir><hr>В программах из всех остальных уроков этой книги функция main() не используется, ее место занимает функция WinMain().<hr></dir>



<p>Выяснив, с чего начинается выполнение программы, давайте рассмотрим то, что она делает - а именно отображение строки на экране при помощи средств ввода/вывода языка C++.



<a name="6"><h3>Что такое потоки C++?</h3></a>



<p>Мы записываем данные в поток C++ с именем cout, для чего используется оператор cout <br><br>

&lt;&lt; "Welcome to C++ \n"n&quot;;: <br>

#include &lt;iostream.hh&gt;<br>



void main()<br>

{<br>

==>	    cout &lt;&lt; "Welcome to C++ \n";<br>

}<br>



<p>Текст "Welcome to C++ \n" отправляется в выходной поток C++ и попадает прямо на экран. Потоки C++ можно рассматривать как каналы для пересылки данных в различные места; поток cout посылает текст на экран.

<p>Символ \n в конце строки представляет собой служебный символ, который переводит курсор на следующую строку после вывода текста. Приведенная выше строка программы выводит сообщение на экране, посылая его в поток cout.

<p>Мы не будем надолго останавливаться на специфике работы с cout, потому что в стандартных Windows-программах вывод текста происходит без участия потоков; мы воспользовались cout лишь для того, чтобы временно облегчить себе задачу. Сейчас он нужен только затем, чтобы мы могли увидеть результаты работы наших классов и объектов при запуске программы. Начиная со следующего урока поток cout нам уже никогда не понадобится.



<dir><hr>Кроме потока cout в консольных программах также можно пользоваться потоком cin для получения символов с клавиатуры.<hr></dir>



<p>На этом наше знакомство с кодом программы first.cpp завершается. Набранная в Visual C++ программа изображена на рис. 1.5. Предварительная подготовка закончена, пора посмотреть, как работает наша программа.



<center><img src="/contents/978580460053/1-5.gif"><br><b>Рис. 1.5.</b> Добавление кода в программу Visual C++</center>





<a name="7"><h3>Запуск первой программы</h3></a>



<p>Чтобы запустить нашу первую программу, сначала необходимо ее откомпилировать, то есть преобразовать в выполняемый файл first.exe. Выполните команду Build д Build First.exe, и исходный файл first.cpp будет скомпилирован в first.exe.

<p>Во время компиляции в окне результатов Visual C++ (в нижней части окна Developer Studio) отображается следующий текст:

<p>---Configuration: first - Win32 Debug---<br>

Compiling...<br>

first.cpp<br>

Linking...<br>



first.exe - 0 error(s), 0 warning(s)<br>



<p>Теперь запустите программу командой Build д Execute first.exe. Результат ее работы изображен на рис. 1.6.



<center><img src="/contents/978580460053/1-6.gif"><br><b>Рис. 1.6.</b> Запуск первой программы</center>



<p>На рис. 1.6 виден текст сообщения Welcome to C++ и подсказка Press any key to continue, вставленная Visual C++. Если нажать любую клавишу, окно исчезнет с экрана.

<p>Только что мы успешно создали и запустили свою первую консольную программу для Win32 - работа с C++ началась. Исходный текст программы из файла first.cpp приведен в листинге (см. ниже).<br>



<p><b>first.cpp</b><br>

#include &lt;iostream.h&gt;<br>



void main()<br>

{<br>

    cout &lt;&lt; "Welcome to C++ \n"&quot;;<br>

}<br>



<p>На примере этой маленькой программы мы познакомились с проектами и рабочими областями Visual C++, с компиляцией программ и с редактированием текстов. Теперь можно заняться собственно программированием на C++. C++ считается объектно-ориентированным языком; сейчас мы выясним, что составляет главную суть этого понятия.



<a name="8"><h3>Классы и объекты C++</h3></a>



<p>Объекты и классы - две фундаментальные концепции всех объектно-ориентированных языков (типа C++). Поскольку эти концепции достаточно важны, мы потратим несколько минут на знакомство с ними, что избавит нас от затрат времени и недоразумений в будущем. Из-за шумихи, поднятой в последнее время, объектно-ориентированное программирование (ООП) может показаться таинственным и неприступным, но это совсем не так. На самом деле ООП было придумано для того, чтобы упростить написание длинных программ. Наш мини-обзор объектно-ориентированного программирования начнется с объектов.



<a name="9"><h3>Что такое объект?</h3></a>



<p>В длинных и сложных программах переменные и функции могут исчисляться сотнями. Это заметно усложняет создание и сопровождение таких программ, поскольку вам приходится помнить обо всем этом. Наличие переменных с одинаковыми именами в различных функциях может привести к нежелательным конфликтам. Объектно-ориентированное программирование как раз и было изобретено для того, чтобы большие программы можно было разделять на отдельные части.

<p>В концепции объектов нет ничего сложного. Программа просто делится на фрагменты, каждый из которых предназначен для решения отдельной задачи; эти фрагменты и называются объектами. Например, весь код для экранного вывода можно выделить в объект с именем screen (экран). Объекты обладают большими возможностями, чем простые функции и переменные, поскольку в них могут содержаться как функции, так и переменные, что облегчает работу с ними. Наш объект screen может содержать не только все данные, отображаемые на экране, но и функции для работы с этими данными, например drawString() (для вывода строк) или drawLine() (для рисования линий). Это означает, что вся работа с экраном изолируется от остальной части программы, что упрощает работу программиста.

<p>Другой пример - представьте себе холодильник. Вряд ли вам захотелось бы постоянно вручную регулировать температуру и управлять работой его насосов. Если же сделать эти функции внутренними и выполняемыми автоматически, холодильник превращается в полезный и удобный объект. Подобное слияние кода с данными в объектах закладывает основу для всего объектно-ориентированного программирования.



<a name="10"><h3>Что такое класс?</h3></a>



<p>Но как создать объект? На помощь приходят классы. Класс для объекта - примерно то же, что форма для печенья; другими словами, класс можно рассматривать как шаблон или "форму" для изготовления объектов. В программировании подобная связь существует между типом данных (например, целочисленным) и переменной. Например, в следующем примере создается целая переменная с именем the_data:<br>

int the_data;<br>



<p>Именно так создаются целочисленные переменные в C++. Здесь int - тип переменной, а the_data - имя самой переменной. Аналогичная связь существует между классом и объектом. Приближенно класс можно рассматривать как тип объекта.



<dir><hr>Как мы вскоре убедимся, C++ поддерживает все стандартные типы данных, принятые в программировании - int, double, long, float и т. д.<hr></dir>



<p>Например, если заранее подготовить класс screenclass, можно создать объект этого класса с именем screen:<br>

<p>screenclass screen;<br>

<p>Важно помнить о том, что все рабочие данные хранятся в объекте. Класс не содержит никаких данных; он лишь описывает общую структуру и поведение объекта.

<p>По своей сути объектно-ориентированное программирование - это всего лишь способ группировки функций и данных, облегчающий работу над программой. По ходу книги мы познакомимся с другими аспектами объектно-ориентированного программирования и научимся создавать классы, создавать объекты классов и обращаться к функциям и данным объектов.

<p>На этом краткий обзор классов и объектов завершается. Подведу итог: класс представляет собой программную конструкцию для объединения (или инкапсуляции) функций и данных. Объект можно рассматривать как переменную, тип которой совпадает с данным классом - подобно тому, как объект screen принадлежал классу screenclass.

<p>В комплект Visual C++ входит целая библиотека заранее написанных классов - Microsoft Foundation Classes (MFC), которая заметно облегчает работу программиста. На ее основе можно создавать объекты для работы с кнопками, текстовыми полями, полосами прокрутки и т. д. Фирма Microsoft уже поработала за нас, и позднее мы воспользуемся этим.

<p>А теперь давайте рассмотрим пример программы, в которой используются классы и объекты.



<a name="11"><h3>Наша первая программа на C++ с классами и объектами</h3></a>



<p>В следующем примере мы создадим класс DataClass и объект этого класса DataObject. Ни класс, ни объект не будут обладать особо впечатляющими возможностями, но зато пример поможет вам разобраться в том, как работают классы и объекты.

<p>Создайте в Visual C++ новый проект с именем classes так, как это было сделано в предыдущем примере. Затем включите в него новый файл с именем classes.cpp. После этого можно добавить код; как и раньше, начнем со включения файла iostream.h:<br>

<p>==>	#include &lt;iostream.h &gt;<br>

    .<br>

    .<br>

    .<br>

<p>После этого объявим новый класс DataClass:<br>

#include &lt;iostream.h&gt;<br>



==>	class DataClass<br>

==>	{<br>



==>	};<br>



<p>Новые классы объявляются с ключевым словом class. Оставшаяся часть объявления класса заключается в фигурные скобки { и }.

<p>Почти во всех объектах C++ хранятся определенные данные; такая возможность будет предусмотрена и в классе DataClass. Для хранения данных используются переменные класса1. Например, в класс можно включить переменную типа int (то есть создать целую переменную класса) с именем PrivateDataMember: <br>

<p>#include &lt;iostream.h&gt;<br>



class DataClass<br>

{<br>

==>	private:<br>

==>	    int PrivateDataMember;<br>

    .<br>

    .<br>

    .<br.

};<br>



<p>Новая переменная класса имеет целый тип и, соответственно, может хранить целочисленные значения. Обратите внимание на ключевое слово private - оно означает, что переменная класса является закрытой, и с ней могут работать только объекты нашего класса DataClass. Ключевое слово private называется модификатором доступа.



<dir><hr>Если опустить модификатор доступа в объявлении класса, по умолчанию используется модификатор private.<hr></dir>



<a name="12"><h3>Что такое модификатор доступа?</h3></a>



<p>Помимо модификатора доступа private, можно воспользоваться модификатором public - он сообщает о том, что переменная класса является открытой и ею можно безо всяких ограничений пользоваться в любом месте программы. Позднее мы познакомимся с третьим модификатором доступа, protected, который ограничивает доступ к переменной и допускает к ней только объекты нашего класса, а также объекты классов, производных от него (вскоре вы поймете, что означает это выражение).

<p>Давайте воспользуемся ключевым словом public и объявим переменную с именем <br>

PublicDataMember:<br>

#include &lt;iostream.h&gt;<br>



class DataClass<br>

{<br>

private:<br>

    int PrivateDataMember&quot;;<br>

==>	public:<br>

==>	    int PublicDataMember;<br>

    .<br>

    .<br>

    .<br>

};<br>



<p>Как мы вскоре убедимся, к этой переменной можно обращаться из любого места программы.

<p>Теперь давайте включим в класс DataClass какую-нибудь функцию. Функции, принадлежащие классу, называются методами1. В нашем примере будет добавлен метод с именем<br>

PublicMethod():<br>

#include &lt;iostream.h&gt;<br>



class DataClasshttp:<br>

{<br>

private:<br>

    int PrivateDataMember;<br>

public:<br>

    int PublicDataMember;<br>

==>	    int PublicMethod(void);<br>

};<br>



<dir><hr>Методы обычно работают с внутренними данными класса, причем подробности этой работы скрываются от внешних частей программы. Это чрезвычайно полезно, поскольку большую программу удается разбить на блоки приемлемого размера. Собственно, объекты были предназначены именно для этой цели.<hr></dir>



<p>Данные передаются методам в виде переменных, которые называются параметрами. Это может выглядеть, например, так: add(variable1, variable2). Метод использует передаваемые данные так, как это делается и в других языках программирования.

<p>Однако наш метод не получает параметров. На это указывает ключевое слово void: int PublicMethod(void) (присутствие void в круглых скобках необязательно - можно написать просто int PublicMethod();). Кроме того, приведенное выше объявление сообщает, что метод возвращает значение целого типа: для этого в начале объявления ставится ключевое слово int. Итак, наш метод не получает параметров и возвращает целое значение.

<p>Метод PublicMethod() объявлен. Остается понять, как же написать его код? Мы отделим определение метода от объявления класса и снабдим определение префиксом DataClass::. Он сообщает Visual C++, к какому классу относится определяемый метод.<br>

#include &lt;iostream.h&gt;<br>



class DataClass<br>

{<br>

private:,br.

    int PrivateDataMember;<br>

public:<br>

    int PublicDataMember;<br>

    int PublicMethod(void);<br>

};<br>



==>	int DataClass::PublicMethod(void)<br>

==>	{<br>



==>	}<br>



<p>Теперь все готово к написанию кода метода. Наш метод не получает параметров, но возвращает целое значение. Какое значение он должен возвращать? Поскольку переменная PrivateDataMember недоступна за пределами класса, пусть метод PublicMethod возвращает ее значение, чтобы его можно было узнать в любом месте программы.



<dir><hr>Обращение к закрытым переменным через методы наподобие PublicMethod() входит в число стандартных приемов программирования; тем самым удается ограничить доступ к закрытым данным класса.<hr></dir>



<p>Код метода PublicMethod() будет выглядеть так (поскольку он принадлежит классу DataClass, то может беспрепятственно обращаться к закрытой переменной PrivateDataMember):<br>

#include &lt;iostream.h&gt;<br>



class DataClass<br>

{<br>

private:<br>

    int PrivateDataMember;<br>

public:<br>

    int PublicDataMember;<br>

    int PublicMethod(void);<br>

};<br.



int DataClass::PublicMethod(void)<br>

{<br>

==>	    return PrivateDataMember;<br>

}<br>



<p>Метод PublicMethod() должен возвращать значение переменной класса PrivateData Member - но какое значение в ней будет храниться? Мы еще не инициализировали эту переменную и не присвоили ей никакого значения, так что возвращаемая методом PublicMethod() величина не будет иметь никакого смысла. Необходимо позаботиться об инициализации PrivateDataMember.



<a name="13"><h3>Инициализация данных класса в конструкторе</h3></a>



<p>Довольно часто приходится присваивать начальное значение данным создаваемого объекта; например, в классе DataClass нужно инициализировать переменную PrivateDataMember. Для этой цели можно создать отдельный метод или же воспользоваться конструктором класса.

<p>Конструктором класса называется специальный метод, который выполняется в программе при создании объекта данного класса. Как мы сейчас увидим, в конструкторе удобно инициализировать данные класса. Имя конструктора совпадает с именем класса, и он не возвращает никакого значения. Тем не менее, конструктору можно передать любое количество параметров. В нашем примере конструктор будет получать всего один параметр - значение, которое должно быть присвоено PrivateDataMember при создании объекта.

<p>Объявление конструктора выглядит так:<br>



#include &lt;iostream.h&gt;<br>



class DataClass<br>

{<br>

private:<br>

    int PrivateDataMember;<br>

public:<br>

==>	    DataClass(int value);<br>

    int PublicDataMember;<br>

    int PublicMethod(void);<br>

};<br>

Затем необходимо определить конструктор:<br>

#include &lt;iostream.h&gt;<br>



class DataClass<br>

{<br>

private:<br>

    int PrivateDataMember;<br>

public:<br>

    DataClass(int Value);<br.

    int PublicDataMember;<br>

    int PublicMethod(void);<br>

};<br>



==>	DataClass::DataClass(int Value)<br>

==>	{<br>



==>	}<br>



<p>В нашем примере достаточно сохранить переданную величину в PrivateDataMember:<br>

#include &lt;iostream.h&gt;<br>



class DataClass<br>

{<br>

private:<br>

    int PrivateDataMember;<br>

public:<br>

    DataClass(int value);<br>

    int PublicDataMember;<br>

    int PublicMethod(void);<br>

};<br>



DataClass::DataClass(int Value)<br>

{<br>

==>	    PrivateDataMember = Value;<br>

}<br>



<p>Готово. У нас есть класс с открытыми и закрытыми переменными и методом, который можно вызывать в программе. Осталось лишь воспользоваться им, и в этом нам поможет функция main().



<a name="14"><h3>Использование класса DataClass</h3></a>



<p>Включите в файл classes.cpp функцию main():<br>

#include &lt;iostream.h&gt;<br>



class DataClass<br>

{<br>

private:<br>

    int PrivateDataMember;<br>

public:<br>

    DataClass(int Value);<br>

    int PublicDataMember;<br>

    int PublicMethod(void);<br>

};<br>



DataClass::DataClass(int Value)<br>

{<br>

    PrivateDataMember = Value;<br>

}<br>



int DataClass::PublicMethod(void)<br>

{<br>

    return PrivateDataMember;<br>

}<br>



==>	void main()<br>

==>	{<br>



==>	}<br>



<p>Функция main() содержит код, выполняемый при запуске программы. Мы начнем ее с объявления объекта класса DataClass. Одновременно с этим мы передадим значение конструктору класса (оно будет присвоено переменной PrivateDataMember). Пусть это будет значение 1; тогда объект DataObject, принадлежащий классу DataClass, будет создаваться следующим образом:<br>



void main()<br>

{<br>

==>	    DataClass DataObject(1);<br>

    .<br>

    .<br>

    .<br>

}<br>



<p>Теперь у нас есть объект с именем DataObject. Он содержит данные, которые мы в него занесли, а также поддерживает метод PublicMethod().

<p>Чтобы присвоить значение открытой переменной класса, PublicDataMember, можно воспользоваться оператором "точка" (.) языка C++. В следующем фрагменте этой переменной присваивается значение 2:<br>

void main()<br>

{<br>

    DataClass DataObject(1);<br>



==>	    DataObject.PublicDataMember = 2;<br>

    .<br>

    .<br>

    .<br>

}<br>



<p>Обычно все обращения к членам объекта (переменным и функциям) происходят именно так. 

<p>Например, мы можем вывести значение переменной PublicDataMember, посылая его в поток<br>

 cout:<br>

void main()<br>

{<br>

    DataClass DataObject(1);<br>



    DataObject.PublicDataMember = 2;<br>



==>	    cout &lt;&lt; &quot;DataObject.PublicDataMember = &quot; <br>

==>	          &lt;&lt; DataObject.PublicDataMember  &lt;&lt; &quot;\n&quot;;<br>

    .<br>

    .<br>

    .<br>

}<br>



<p>Но как получить значение, присвоенное PrivateDataMember? Поскольку код в функции main() не принадлежит объекту DataObject, из него нельзя напрямую обратиться к закрытой переменной этого объекта. Чтобы добраться до нее, надо вызвать метод PublicMethod() и вывести полученное значение:<br>

void main()<br>

{<br>

    DataClass DataObject(1);<br>



    DataObject.PublicDataMember = 2;<br>



    cout &lt;&lt; &quot;DataObject.PublicDataMember = &quot; <br>

         &lt;&lt; DataObject.PublicDataMember &lt;&lt; &quot;\n&quot;;<br>

    cout &lt;&lt; "DataObject.PrivateDataMember = &quot; <br>

         &lt;&lt; DataObject.PublicMethod() &lt;&lt; &quot;\n&quot;;<br>



}<br>



<p>Программа работы с классами готова - запустите ее. Результаты ее работы изображены на рис. 1.7. Как видно из рисунка, нам удалось вывести значения и открытой, и закрытой переменных объекта DataClass. Первое знакомство с классами и объектами C++ состоялось.



<center><img src="/contents/978580460053/1-7.gif"><br><b>Рис. 1.7.</b> Запуск программы classes</center>



<p>Ниже приведен полный текст программы из файла classes.cpp.<br>



<b>classes.cpp</b><br>

#include &lt;iostream.h&gt;<br>



class DataClass<br>

{<br>

private:<br>

    int PrivateDataMember;<br>

public:<br>

    DataClass(int Value);<br>

    int PublicDataMember;<br>

    int PublicMethod(void);<br>

};<br>



DataClass::DataClass(int Value)<br>

{<br>

    PrivateDataMember = Value;<br>

}<br>



int DataClass::PublicMethod(void)<br>

{<br>

    return PrivateDataMember;<br>

}<br>



void main()<br>

{<br>

    DataClass DataObject(1);<br>



    DataObject.PublicDataMember = 2;<br>



   cout &lt;&lt; &quot; DataObject.PublicDataMember = &quot; <br>

        &lt;&lt; DataObject.PublicDataMember &lt;&lt; &quot;\n&quot;;<br>

    cout &lt;&lt;&quot;  DataObject.PrivateDataMember = &quot; <br>

         &lt;&lt; DataObject.PublicMethod() &lt;&lt; &quot;\n&quot;;<br>



}<br>



<p>Наш первый пример был крайне примитивным - он всего лишь показал, как создать класс и объект в программе на C++. Он совершенно не раскрывает основной смысл объектов - хранение данных и внутреннюю работу с ними. Сейчас мы рассмотрим более реальный пример, который покажет, как работают объекты и для чего они нужны.



<a name="15"><h3>Реальный пример на C++</h3></a>



<p>Давайте рассмотрим более жизненный пример на C++, который бы продемонстрировал возможности объектов по внутренней обработке данных.

<p>Предполагается, что в новом примере мы будем обрабатывать для двух учебных предметов - истории и английского языка - результаты контрольных работ. Мы создадим объект, сохраняющий все оценки и вычисляющий средний балл по каждому предмету. Новый пример называется schoolroom.

<p>Создайте проект schoolroom и добавьте в него новый файл schoolroom.cpp. Мы создадим класс с именем SchoolClass для хранения и обработки оценок:<br>

#include &lt;iostream.h&gt;<br>



==>	class SchoolClass {<br>



==>	};<br>

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



<dir><hr>Указатель - это переменная, в которой хранится адрес области памяти. В языках C и C++ имя массива представляет собой указатель на начало данных массива в памяти. Чтобы объявить указатель в C и C++, следует снабдить имя переменной префиксом * ("звездочка").<hr></dir>

<p>Мы также создадим в области данных целую индексную переменную ClassDataIndex, определяющую наше положение относительно начала массива при добавлении сведений о новом ученике:<br>

#include &lt;iostream.h&gt;<br>



class SchoolClass {<br>

==>	    int *ClassData;<br>

==>	    int ClassDataIndex;<br>



};<br>



<p>Область памяти для хранения оценок разумнее всего выделять в конструкторе класса. Мы передадим ему количество студентов, по которому можно будет определить размеры выделяемой области. Также обратите внимание, как мы инициализируем в конструкторе индексную переменную ClassDataIndex значением 0:<br>

#include &lt;iostream.h&gt;<br>



class SchoolClass {<br>

    int *ClassData;<br>

    int ClassDataIndex;<br>

public:<br>

==>	    SchoolClass(int NumberStudents);<br>

    .<br>

    .<br>

    .<br>

};<br>



==>	SchoolClass::SchoolClass(int NumberStudents);<br>

{<br>

==>	    ClassData = new int[NumberStudents];<br>

==>	    ClassDataIndex = 0;<br>

}<br>



<p>Память для хранения данных выделяется с помощью оператора C++ new. В данном случае выделяется область, размера которой достаточно для хранения NumberStudents целых чисел. Оператор new является встроенным оператором C++ и используется вместо таких функций C, как malloc() и calloc(). Мы неоднократно встретимся с ним в этой книге.

<p>При желании можно рассматривать выделенную область памяти как массив (в C и C++ имена массивов и указатели считаются практически синонимами). Тогда для обращения к первому целому в выделенной области можно использовать запись ClassData[0], к следующему - ClassData[1] и т. д.

<p>Итак, мы выделили область памяти, которая будет интерпретироваться как массив, и размера которой хватает для хранения NumberStudents целых значений оценок.

<p>Но как избавиться от выделенной области, когда необходимость в ней отпадет? Помимо конструкторов в C++ существуют деструкторы - они вызываются при уничтожении объекта и содержат код "сборки мусора". В нашем примере деструктор будет уничтожать выделенную ранее область памяти.



<a name="16"><h3>Деструкторы C++</h3></a>



<p>Деструктор отчасти похож на конструктор, только он автоматически вызывается при уничтожении объекта. Между ними существует даже внешнее сходство, но имя деструктора снабжается префиксом ~ ("тильда"):<br>

#include &lt;iostream.h&gt;<br>



class SchoolClass {<br>

    int *ClassData;<br>

    int ClassDataIndex;<br>

public:<br>

    SchoolClass(int NumberStudents);<br.

==>	    ~SchoolClass(void);<br>

    .<br>

    .<br>

    .<br>

};<br>



SchoolClass::SchoolClass(int NumberStudents);<br>

{<br>

    ClassData = new int[NumberStudents];<br>

    ClassDataIndex = 0;<br>

}<br>



==>	SchoolClass::~SchoolClass(void)<br>

==>	{<br>



==>	}<br>



<p>Деструктор должен вернуть системе область памяти, выделенную при выполнении конструктора. Для оператора new существует противоположный по смыслу оператор delete, при помощи которого можно уничтожить массив:<br>

SchoolClass::~SchoolClass(void)<br>

{<br>

==>	    delete ClassData;<br>

}<br>



<p>Теперь у нашего класса есть и конструктор, и деструктор, но возникает новая проблема - класс не может существовать в вакууме. Нам потребуются методы для занесения оценок в объект и последующего их получения.

<p>Другими словами, в созданный объект класса SchoolClass необходимо записать данные и предоставить некоторые средства для работы с ними. Эта идея лежит в основе всех объектов - обычно они применяются для хранения и обработки внутренних данных.



<a name="17"><h3>Сохранение, извлечение и обработка данных</h3></a>



<p>Для работы с данными в классе SchoolClass нам понадобятся три метода:



<ul><li>Метод AddScore для занесения оценки очередного ученика во внутренний массив объекта.

<li>Метод GetScore для извлечения оценки из внутреннего (закрытого) массива.

<li>Метод AverageScore для вычисления среднего балла всех учеников по данному предмету.</ul>



<p>Эти три метода воплощают основные идеи работы с данными - сохранение данных, их извлечение и обработку.

<p>Методы AddScore и GetScore() выглядят просто, поэтому с них мы и начнем.



<a name="18"><h3>Сохранение данных методом AddScore()</h3></a>



<p>Метод AddScore() должен заносить новую оценку во внутренний массив объекта. В нашем примере он будет выглядеть так:<br>

#include &lt;iostream.h&gt;<br>



class SchoolClass {<br>

    int *ClassData;<br>

    int ClassDataIndex;<br>

public:<br>

    SchoolClass(int NumberStudents);<br>

    ~SchoolClass(void);<br>

==>	    void AddScore(int Score);<br>

};<br>

    .<br>

    .<br>

    .<br>

==>	void SchoolClass::AddScore(int Score)<br>

==>	{<br>

==>	    ClassData[ClassDataIndex++] = Score;<br>

==>	}<br>



<p>В методе AddScore() мы сохраняем новую оценку, переданную в качестве параметра, во внутреннем массиве и увеличиваем значение индексной переменной. Обратите внимание на то, как это делается: ClassDataIndex++.

<p>Знаменитый оператор ++ языка C++ увеличивает значение аргумента. При использовании постфиксной записи (как в нашем примере) значение аргумента увеличивается после выполнения текущего оператора. Префиксная запись (++ClassDataIndex) увеличивает значение аргумента ClassDataIndex перед выполнением оператора.



<dir><hr>В C++ также имеется оператор -, который уменьшает значение аргумента. Он также может использоваться в префиксной или постфиксной записи.<hr></dir>



<p>Следующим идет метод GetScore(), в котором мы извлекаем из массива оценку с заданным индексом и возвращаем ее.



<a name="19"><h3>Извлечение данных методом GetScore()</h3></a>



<p>Когда мы вызываем метод GetScore() и передаем ему значение индекса, необходимо, чтобы он возвращал оценку, которая хранится с заданным смещением во внутреннем массиве данных. Напишем метод GetScore().

<p>Прежде всего метод GetScore() должен проверять, не превышает ли передаваемый индекс общего количества сохраненных оценок. Если переданный индекс будет признан допустимым, метод возвращает его:<br>

#include &lt;iostream.h&gt;<br>



class SchoolClass {<br>

    int *ClassData;<br>

    int ClassDataIndex;<br>

public:<br>

    SchoolClass(int NumberStudents);<br>

    ~SchoolClass(void);<br>

    void AddScore(int Score);<br>

==>	    int GetScore(int Index);<br>

    .<br>

    .<br>

    .<br>

};<br>



==>	int SchoolClass::GetScore(int Index)<br>

==>	{<br>

==>	    if(Index &lt;= ClassDataIndex)<br>

==>	    {<br>

==>	        return ClassData[Index];<br>

==>	    }<br>

    .<br>

	    .<br>

	    .<br>

}<br>



<p>В противном случае затребованная оценка еще не была сохранена во внутреннем массиве, поэтому в условии else оператора if мы возвращаем значение -1 (условие else выполняется, если выражение, проверяемое в операторе if, оказалось ложным).<br>

#include &lt;iostream.h&gt;<br>



class SchoolClass {<br>

    int *ClassData;<br>

    int ClassDataIndex;<br>

public:<br>

    SchoolClass(int NumberStudents);<br>

    ~SchoolClass(void);<br>

    void AddScore(int Score);<br>

    int GetScore(int Index);<br>

    .<br>

    .<br>

    .<br>

};<br>



int SchoolClass::GetScore(int Index)<br>

{<br>

    if(Index <= ClassDataIndex)<br>

    {<br>

        return ClassData[Index];<br>

    }<br>

==>	    else<br>

==>	    {<br>

==>	        return -1;<br>

==>	    }<br>

==>	}<br>



<p>На этом завершается наше изучение методов сохранения и извлечения данных  AddScore() и GetScore().

<p>Остается написать метод AverageScore() для работы с сохраненными данными. Он возвращает среднее значение по всем сохраненным ранее оценкам.



<a name="20"><h3>Вычисление средней оценки методом AverageScore()</h3></a>



<p>В методе AverageScore() мы суммируем все оценки в вещественной (float) переменной Sum, а затем делим полученную величину на общее количество сохраненных оценок. Результат вычисления метод возвращает во внешнюю часть программы.

<p>Для работы с вещественной переменной Sum нам придется временно интерпретировать целые значения оценок как вещественные числа. Для этого служит преобразование типов: (float)ClassData[loop_index]. Такая запись временно интерпретирует целое значение ClassData[loop_index] как вещественное, которое прибавляется к текущему значению накапливаемой суммы. Также обратите внимание на то, что при отсутствии данных для вычисления средней оценки возвращается значение -1:<br>

#include &lt;iostream.h&gt;<br>



class SchoolClass {<br>

    int *ClassData;<br>

    int ClassDataIndex;<br>

public:<br>

    SchoolClass(int NumberStudents);<br>

    ~SchoolClass(void);<br>

    void AddScore(int Score);<br>

    int GetScore(int Index);<br>

==>	    float AverageScore(void);<br>

};<br>

    .<br>

    .<br>

    .<br>

==>	float SchoolClass::AverageScore(void)<br>

==>	{<br>

==>	    float Sum = 0;<br>



==>	    if(ClassDataIndex == 0)<br>

==>	    {<br>

==>	        return -1;<br>

==>	    }<br>



==>	    for(int loop_index = 0; loop_index < ClassDataIndex; loop_index++)<br>

==>	    {<br>

==>	        Sum += (float) ClassData[loop_index];<br>

==>	    }<br>

    .<br>

	    .<br>

	    .<br>

	}<br>



<dir><hr>В функции AverageScore() мы воспользовались циклом for C++, который выглядит так:<br>

for(начало; конец; действие)<br>

{<br>

   [тело цикла]<br>

}<br>

<p>Цикл начинается с выполнения оператора начало, затем проверяется условие конец, после чего выполняется тело цикла. После этого выполняется оператор действие, обычно увеличивающий значение переменной цикла.<hr></dir>



<p>Возможно, вы обратили внимание на одну интересную особенность - переменная цикла loop_index объявляется прямо внутри цикла (int loop_index = 0):<br>

==>	    for(int loop_index = 0; loop_index < ClassDataIndex; loop_index++)<br>

    {<br>

	        Sum += (float) ClassData[loop_index];<br>

	    }<br>



<p>В этом заключается одна из приятных особенностей C++: объявление переменной можно отложить до того момента, когда она вам понадобится в программе. Вы не обязаны объявлять все переменные в начале функции, как это делалось в языках типа C.

Мы сохранили сумму всех оценок в переменной с именем Sum. Остается разделить ее на общее количество оценок, чтобы определить средний балл и передать его как значение, возвращаемое методом AverageScore:

#include &lt;iostream.h&gt;<br>



class SchoolClass {<br>

    int *ClassData;<br>

    int ClassDataIndex;<br>

public:<br>

    SchoolClass(int NumberStudents);<br>

    ~SchoolClass(void);<br>

    void AddScore(int Score);<br>

    int GetScore(int Index);<br>

==>	    float AverageScore(void);<br>

};<br>

    .<br>

    .<br>

    .<br>

==>	float SchoolClass::AverageScore(void)<br>

==>	{<br>

==>	    float Sum = 0;<br>



==>	    if(ClassDataIndex == 0)<br>

==>	    {<br>

==>	        return -1;<br>

==>	    }<br>



==>	    for(int loop_index = 0; loop_index < ClassDataIndex; loop_index++)<br>

==>	    {<br>

==>	        Sum += (float) ClassData[loop_index];<br>

==>	    }<br>



==>	    return Sum / (float) ClassDataIndex;<br>

}<br>



<p>Класс SchoolClass готов; он содержит методы для сохранения, извлечения и обработки данных. Настало время применить его на практике.



<a name="21"><h3>Использование класса SchoolClass в программе</h3></a>



<p>Мы будем работать с классом SchoolClass в функции main(), которую тоже необходимо включить в файл schoolroom.cpp:<br>

void main()<br>

{<br>



}<br>



<p><ol><li>	Начнем с объявления двух объектов класса SchoolClass: в объекте HistoryClass будут храниться оценки по истории, а в объекте EnglishClass - оценки по английскому языку:<br>

void main()<br>

{<br>

    SchoolClass HistoryClass(9);<br>

    SchoolClass EnglishClass(10);<br>

    .<br>

    .<br>

    .<br>

}<br>



<p><li>Заполним внутренние массивы этих объектов данными с помощью метода AddScore():<br>

void main()<br>

{<br>

    SchoolClass HistoryClass(9);<br>

    SchoolClass EnglishClass(10);<br>



==>	    HistoryClass.AddScore(80);<br>

	    HistoryClass.AddScore(81);<br>

	    HistoryClass.AddScore(82);<br>

	    HistoryClass.AddScore(83);<br>

	    HistoryClass.AddScore(84);<br>

	    HistoryClass.AddScore(85);<br>

	    HistoryClass.AddScore(86);<br>

	    HistoryClass.AddScore(87);<br>

	    HistoryClass.AddScore(88);<br>



==>	    EnglishClass.AddScore(91);<br>

	    EnglishClass.AddScore(92);<br>

	    EnglishClass.AddScore(93);<br>

	    EnglishClass.AddScore(94);<br>

	    EnglishClass.AddScore(95);<br>

	    EnglishClass.AddScore(96);<br>

	    EnglishClass.AddScore(97);<br>

	    EnglishClass.AddScore(98);<br>

	    EnglishClass.AddScore(99);<br>

	    EnglishClass.AddScore(100);<br>

    .<br>

    .<br>

    .<br>

}<br>



<li>Осталось лишь вывести средние оценки по обоим предметам:<br>

void main()<br>

{<br>

    SchoolClass HistoryClass(9);<br>

    SchoolClass EnglishClass(10);<br>



    HistoryClass.AddScore(80);<br>

    HistoryClass.AddScore(81);<br>

    HistoryClass.AddScore(82);<br>

    HistoryClass.AddScore(83);<br>

    HistoryClass.AddScore(84);<br>

    HistoryClass.AddScore(85);<br>

    HistoryClass.AddScore(86);<br>

    HistoryClass.AddScore(87);<br>

    HistoryClass.AddScore(88);<br>



    EnglishClass.AddScore(91);<br>

    EnglishClass.AddScore(92);<br>

    EnglishClass.AddScore(93);<br>

    EnglishClass.AddScore(94);<br>

    EnglishClass.AddScore(95);<br>

    EnglishClass.AddScore(96);<br>

    EnglishClass.AddScore(97);<br>

    EnglishClass.AddScore(98);<br>

    EnglishClass.AddScore(99);<br>

    EnglishClass.AddScore(100);<br>



==>	    cout &lt;&lt; &quotAverage score for History class: &quot <br>

==>	         &lt;&lt; HistoryClass.AverageScore() &lt;&lt; &quot\n&quot;<br>

==>	    cout &lt;&lt; &quotAverage score for English class: &quot <br>

==>	         &lt;&lt; EnglishClass.AverageScore() &lt;&lt; &quot\n&quot;<br>



}<br>



<li>Программа schoolroom готова к работе. Запустите ее - результаты работы программы изображены на рис. 1.8. В этом примере мы занесли данные в объекты класса SchoolClass и вычислили их средние значения - объекты успешно справились с обработкой данных.</ol>



<p>Объекты помогли разбить программу на более мелкие и удобные блоки - именно в этом состоит их основное назначение. Ниже приведен полный текст программы из файла schoolroom.cpp.<br>



<b>schoolroom.cpp</b><br>

#include &lt;iostream.h&gt;<br>



class SchoolClass {<br>

    int *ClassData;<br>

    int ClassDataIndex;<br>



<center><img src="/contents/978580460053/1-8.gif"><br><b>Рис. 1.8.</b> Запуск программы schoolroom</center>



<p>public:<br>

    SchoolClass(int NumberStudents);<br>

    ~SchoolClass(void);<br>

    void AddScore(int Score);<br>

    int GetScore(int Index);<br>

    float AverageScore(void);<br>

};<br>



SchoolClass::SchoolClass(int NumberStudents)<br>

{<br>

    ClassData = new int[NumberStudents];<br>

    ClassDataIndex = 0;<br>

}<br>



SchoolClass::~SchoolClass(void)<br>

{<br>

    delete ClassData;<br>

}<br>



void SchoolClass::AddScore(int Score)<br>

{<br>

    ClassData[ClassDataIndex++] = Score;<br>

}<br>



int SchoolClass::GetScore(int Index)<br>

{<br>

    if(Index <= ClassDataIndex)<br>

    {<br>

        return ClassData[Index];<br>

    }<br>

    else<br>

    {<br>

        return -1;<br>

    }<br>

}<br>



float SchoolClass::AverageScore(void)<br>

{<br>

    float Sum = 0;<br>



    if(ClassDataIndex == 0)<br>

    {<br>

        return -1;<br>

    }<br>



    for(int loop_index = 0; loop_index &lt; ClassDataIndex; loop_index++)<br>

    {<br>

        Sum += (float) ClassData[loop_index];<br>

    }<br>

    

    return Sum / (float) ClassDataIndex;<br>

}<br>



void main()<br>

{<br>

    SchoolClass HistoryClass(9);<br>

    SchoolClass EnglishClass(10);<br>



    HistoryClass.AddScore(80);<br>

    HistoryClass.AddScore(81);<br>

    HistoryClass.AddScore(82);<br>

    HistoryClass.AddScore(83);<br>

    HistoryClass.AddScore(84);<br>

    HistoryClass.AddScore(85);<br>

    HistoryClass.AddScore(86);<br>

    HistoryClass.AddScore(87);<br>

    HistoryClass.AddScore(88);<br>



    EnglishClass.AddScore(91);<br>

    EnglishClass.AddScore(92);<br>

    EnglishClass.AddScore(93);<br>

    EnglishClass.AddScore(94);<br>

    EnglishClass.AddScore(95);<br>

    EnglishClass.AddScore(96);<br>

    EnglishClass.AddScore(97);<br>

    EnglishClass.AddScore(98);<br>

    EnglishClass.AddScore(99);<br>

    EnglishClass.AddScore(100);<br>



    cout &lt;&lt; &quot;Average score for History class: &quot; <br>

          &lt;&lt; HistoryClass.AverageScore()  &lt;&lt; &quot;\n&quot;;<br>

    cout  &lt;&lt; &quot;Average score for English class: &quot;<br>

         &lt;&lt; EnglishClass.$AverageScore() << &quot;\n&quot;;<br>



}<br>



<p>Наши первые программы на C++ работают, но перед тем как переходить к следующему уроку, стоит познакомиться еще с несколькими важными концепциями: наследованием, переопределением и перегрузкой.



<a name="22"><h3>Что такое наследование и переопределение?</h3></a>



<p>Наследование - еще одна важная составляющая объектно-ориентированного программирования. Благодаря ему производные классы наследуют функциональность базовых и добавляют к ней свои собственные возможности. Например, мы можем создать базовый класс vehicle (транспортное средство) и породить от него два производных класса: truck (грузовик) и helicopter (вертолет). Оба имеют один и тот же базовый класс (и содержат все методы базового класса), что экономит время при программировании.

<p>Хотя классы helicopter и truck порождаются от одного и того же базового класса vehicle, каждый из них по-своему модифицирует его поведение, так что в итоге мы получаем два вполне самостоятельных класса.



<dir><hr>Помните об отличиях между модификаторами доступа private, protected и public. К открытым (public) членам класса можно обращаться из любого места программы, к закрытым (private) - только из объектов того же класса, а к защищенным (protected) - из объектов того же самого или производных от него классов.<hr></dir>



<p>Оба производных класса могут пользоваться методами vehicle, например, start() (завести) или move() (двигаться). Однако вертолет движется иначе, чем грузовик. Как дополнить или даже изменить поведение класса vehicle, чтобы приспособить его для новых классов? Одна из возможностей заключается в переопределении методов базового класса (переопределение методов считается важной составляющей объектно-ориентированного программирования). Когда мы переопределяем метод базового класса в производном классе, новая версия метода полностью заменяет старую. Таким образом мы можем изменить поведение базового класса в производном классе и заставить его вести себя так, как нам нужно.

<p>Давайте посмотрим, как наследование и переопределение применяются на практике. Создайте новый проект с именем inheritance. Объявим класс транспортного средства vehicle с двумя методами, start() и move():<br>

#include &lt;iostream.h&gt;<br>



==>	class vehicle {<br>

==>	public: void start();<br>

==>	    void move();<br>

==>	};<br>



<p>Метод start() класса vehicle в нашем примере будет просто выводить строку "Starting...", а метод move() - строку "Driving...":<br>

#include &lt;iostream.h&gt;<br>



class vehicle {<br>

public: void start();<br>

    void move();<br>

};<br>



==>	void vehicle::start() { cout &lt;&lt; "Starting...\n&quot;;}<br>

==>	void vehicle::move() { cout &lt;&lt; "Driving...\nn&quot;;}<br>

.<br>

.<br>

.<br>



<p>Теперь создадим новый класс helicopter и сделаем его производным от класса vehicle.



<a name="23><h3>Создание производного класса</h3></a>



<p>Класс helicopter порождается от базового класса vehicle так:<br>

#include &lt;iostream.h&gt;<br>



class vehicle {<br>

public: void start();<br>



    void move();<br>

};<br>



==>	class helicopter : public vehicle {<br>



==>	};<br>



<p>Чтобы сделать класс helicopter производным от класса vehicle, следует после объявления класса helicopter поставить двоеточие и указать имя базового класса (vehicle):<br>

==>	class helicopter : public vehicle {<br>

    .<br>

    .<br>

    .<br>

};<br>



<p>Поскольку класс helicopter является производным от vehicle, он изначально содержит методы класса vehicle: start() и move().



<a name="24><h3>Изменение метода - переопределение</h3></a>



<p>Однако метод move() класса vehicle выводит строку "Driving..." (то есть "Еду..."), а для вертолета это не подходит. Следовательно, мы должны переопределить метод move() в классе helicopter так, чтобы он выводил строку "Flying..." (то есть "Лечу..."):<br>

#include &lt;iostream.h&gt;<br>



class vehicle {<br>

public: void start();<br>

    void move();<br>



};<br>



class helicopter : public vehicle {<br>

==>	public: void move();<br>

};<br>



void vehicle::start() { cout &lt;&lt; &quot;Starting...\n&quot;;}<br>

void vehicle::move() { cout &lt;&lt; &quot;Driving...\n&quot;;}<br>



==>	void helicopter::move() { cout << "Flying...\n";}<br>

    .<br>

    .<br>

    .<br>



<p>Методы start() и move() класса helicopter можно свободно вызывать в функции main():<br>

#include &lt;iostream.h&gt;<br>



class vehicle {<br>

public: void start();<br>

    void move();<br>

};<br>



class helicopter : public vehicle {<br>

public: void move();<br>

};<br>



void vehicle::start() { cout &lt;&lt; &quot;Starting...\n&quot;;}<br>

void vehicle::move() { cout &lt;&lt; &quot;Driving...\n&quot;;}<br>



void helicopter::move() { cout &lt;&lt; &quot;Flying...\n&quot;;}<br>



==>	void main()<br>

==>	{<br>

==>	    helicopter whirly;<br>



==>	    whirly.start();<br>

==>	    whirly.move();<br>

==>	}<br>



<p>Программа для демонстрации наследования готова - запустите ее. Результат ее работы изображен на рис. 1.9. Как видно на рисунке, переопределенный метод move() успешно работает и выводит строку "Flying..." вместо "Driving...". В этой программе мы познакомились с техникой наследования и переопределения методов в C++. Ниже приведен полный текст программы из файла inheritance.cpp.



<center><img src="/contents/978580460053/1-9.gif"><br><b>Рис. 1.9.</b> Переопределение метода в C++</center>





<b>inheritance.cpp</b><br>

#include &lt;iostream.h&gt;<br>



class vehicle {<br>

public: void start();<br>

    void move();<br>

};<br>



class helicopter : public vehicle {<br>

public: void move();<br>

};<br>



void vehicle::start() { cout &lt;&lt; &quot;Starting...\n&quot;;}<br>

void vehicle::move() { cout &lt;&lt; &quot;Driving...\n&quot;;}<br>



void helicopter::move() { cout &lt;&lt; &quot;Flying...\n&quot;;}<br>



void main()<br>

{<br>

    helicopter whirly;<br>



    whirly.start();<br>

    whirly.move();<br>

}<br>



<p>В этом уроке нам осталось рассмотреть лишь перегрузку функций. Этим мы сейчас и займемся.



<a name="25"><h3>Перегрузка функций в C++</h3></a>

<p>В С++ один и тот же метод можно вызывать с различными типами и даже различным количеством параметров. Например, может существовать метод display(), отображающий на экране отдельный символ, используя для этого тип char С++, или же целую строку символов, которая в стандартном C++ интерпретируется как массив символов. Иначе говоря, метод display() может вызываться как для отдельного символа, так и для массива символов. Рассмотрим как это делается на примере новой программы overloading. Создайте проект, а в нем - файл overloading.cpp.

<p>Здесь в функции main() будет создаваться новый объект DisplayObject:<br>

void main()<br>

{<br>

==>	    DisplayClass DisplayObject;<br>

    .<br>

    .<br>

    .<br>

}<br>



<p>В этом объекте будет находиться метод display(). Сначала мы вызовем его для отображения единственного символа "h":<br>

void main()<br>

{<br>

    DisplayClass DisplayObject;<br>



==>	    DisplayObject.display(&quot;h&quot;);<br>

    .<br>

    .<br>

    .<br>

}<br>



<p>Тот же метод можно вызвать и для строки (то есть массива символов), которая в нашем примере состоит всего лишь из одной буквы "i" (в C++ кавычки говорят о том, что речь идет о строке, а не об отдельном символе):<br>

void main()<br>

{<br>

    DisplayClass DisplayObject;<br>



    DisplayObject.display(&quot;h&quot;);<br>

==>	    DisplayObject.display(&quot;i&quot;);<br>

    cout << &quot;\n&quot;;<br>

}<br>



<p>Один и тот же метод вызывается для аргументов двух типов - символа и строки. Но как это сделать? В C++ это совсем не сложно - нужно лишь определить метод дважды, по одному разу для каждого типа предполагаемых параметров. Повторное определение метода display() может выглядеть так:<br>

#include &lt;iostream.h&gt;<br>



class DisplayClass <br>

{<br>

public:<br>

==>	    void display(char character);<br>

==>	    void display(char* string);<br>

};<br>



==>	void DisplayClass::display(char character)<br>

==>	{<br>

==>	    cout << character;<br>

==>	}<br>



==>	void DisplayClass::display(char* string)<br>

==>	{<br>

==>	    cout << string;<br>

==>	}<br>



<p>Но как C++ определяет, какую версию display() использовать при вызове метода? По типу передаваемого параметра. Например, если параметр относится к символьному типу, вызывается версия display() для символьного параметра. Если же передать ему строку, будет использована вторая версия.

<p>Запустите программу; результат ее работы изображен на рис. 1.10. Как видно из рисунка, перегрузка метода display() прошла успешно. В этой книге мы будем пользоваться этой методикой достаточно часто.





<center><img src="/contents/978580460053/1-10.gif"><br><b>Рис. 1.10.</b> Перегрузка метода в C++</center>



Ниже приведен полный текст программы из файла overloading.cpp.<br>

<b>overloading.cpp</b><br>

#include &lt;iostream.h&gt;<br>



class DisplayClass <br>

{<br>

public:<br>

    void display(char character);<br>

    void display(char* string);<br>

};<br>



void DisplayClass::display(char character)<br>

{<br>

    cout << character;<br>

}<br>



void DisplayClass::display(char* string)<br>

{<br>

    cout << string;<br>

}<br>



void main()<br>

{<br>

    DisplayClass DisplayObject;<br>



    DisplayObject.display(&quot;h&quot;);<br>

    DisplayObject.display(&quot;i&quot;);<br>

    cout << &quot;\nquot;;<br>

}<br>

В этом уроке мы узнали немало нового, познакомились со многими основными понятиями C++ - классами, объектами, наследованием, перегрузкой, переопределением и т. д. В следующем уроке мы увидим, как применить их на практике при создании настоящих программ для Windows.

Если изложенный материал не вызвал у вас особых затруднений, переходите к уроку 2. В противном случае вам стоит почитать дополнительную литературу по программированию, потому что в следующем уроке мы займемся Visual C++ вплотную.





<p><a name="26"><h3>Что нового мы узнали?</h3></a>

В этом уроке мы:

<ul><li>Познакомились с концепциями классов и объектов C++.

<li>Узнали, как пользоваться наследованием C++.

<li>Научились пользоваться конструкторами и деструкторами.

<li>Научились перегружать методы, чтобы они получали параметры различных типов.

<li>Научились изменять методы базового класса с помощью переопределения C++.</ul>

</font></p>


		<noindex>
			<br/>
			<div align="center">
				
			</div>
		</noindex>
		
					
		</td>
<body><html>
<td>
	<!--trust-->
	</td>
<td>
	</td></table></body></html>
------------wOCwWjjIy35ybHEPCvEFB0
Content-Disposition: inline; filename=main.css
Content-Type: text/css; charset=windows-1251; name=main.css
Content-Location: http://www.piter-press.ru/main.css?a=111
Content-Transfer-Encoding: 8bit

body {
    background-color: #FFFFFF;
    font-size:11px;
    font-family:verdana, tahoma, arial;
    padding:0;
    margin:0;
    color: #333333;
    margin-left: 0px;
    margin-top: 0px;
    margin-right: 0px;
    margin-bottom: 0px;
}

font, span, p, div, li, td, input, option, select {
	font-size:11px;
	color:#222;
}

a, a:visited {
    color: #004191;
    text-decoration: none;
}

a:hover {
    color:#da4500;
    text-decoration:underline;
}

/*
a.orangeLink:hover {
    text-decoration:none;
}
*/

.areas {
 font-size:12px;
}

img {
    border:0;
}


.withborder {
 border-color:#c1cdd7;
 border-width:1px;
 border-style:Solid;
 border-collapse:collapse;
}

.withborder td {
 border-color:#c1cdd7;
 border-width:1px;
 border-style:Solid;
 border-collapse:collapse;
}


.withoutborder {
 border-color:#FFFFFF;
 border-width:1px;
 border-style:Solid;
 border-collapse:collapse;
}

.withoutborder td {
 border-color:#FFFFFF;
 border-width:1px;
 border-style:Solid;
 border-collapse:collapse;
}


a.top_menu:active{
color: #ffffff;
text-decoration: none;
}

a.top_menu:visited{
color: #ffffff;
text-decoration: none;
}

a.top_menu:hover{
color: #ffffff;
text-decoration: none;
}

a.top_menu:link{
color: #ffffff;
text-decoration: none;
}

a.top_menu_deact
{
font-family:Arial, Helvetica, sans-serif;
font-size:12px;
color: #f5f5f5;
text-decoration: none;
}




a.top_menu_deact:active
{
color: #ffffff;
text-decoration: none;
}
a.top_menu_deact:visited
{
color: #ffffff;
text-decoration: none;
}
a.top_menu_deact:hover
{
color: #ffffff;
text-decoration: none;
}
a.top_menu_deact:link
{
color: #e6e6e6;
text-decoration: none;
}

a.top_menu_2
{
font-family:tahoma, verdana, sans-serif;
font-size:11px;
color: #ffffff;
text-decoration: none;
}

a.top_menu_2:active
{
color: #ffffff;
text-decoration: none;
}
a.top_menu_2:visited
{
color: #ffffff;
text-decoration: none;
}
a.top_menu_2:hover
{
color: #ffffff;
text-decoration: underline;
}
a.top_menu_2:link
{
color: #ffffff;
text-decoration: none;
}

a.top_menu_2:hover
{
font-family:tahoma, verdana, sans-serif;
font-size:11px;
color: #ffffff;
text-decoration: underline;
}


.notable {
	margin: 0;
	padding: 0;
	
}
.menu_active {
	background-image: url('/i/m_active.gif');
	background-repeat: repeat-x;
	padding-left:8px;
	padding-right:8px;
}

.menu_deactive {
	background-image: url('/i/m_deactive.gif');
	background-repeat: repeat-x;
	padding-left:6px;
	padding-right:6px;
}

.menu_bullet {
	 width: 7px;
	 height:26px;
	 margin-left:12px;
	 margin-right:6px;
	 border:none;
}

.nav_act {
	font-family: Arial, Helvetica, sans-serif;
	font-size: 12px;
	font-weight: bold;
	color: #FFFFFF;
}

.nav_deact {
	font-family: Arial, Helvetica, sans-serif;
	font-size: 12px;
	color: #FFFFFF;
}

.right_column {
	border-left-style: dotted;
	border-left-color:#666666;
	border-left-width: 1px;
}
.left_content {
	padding-top: 0px;
	padding-right: 23px;
	padding-bottom: 30px;
	padding-left: 30px;
}
.pd12 {
	padding-top: 0px;
	padding-right: 0px;
	padding-bottom: 0px;
	padding-left: 12px;
}

sup.discount {
 	color: #da4500;
	font-weight: bold;
	font-size: 14px;
}

.news_h2 {
	font-family: Arial, Helvetica, sans-serif;
	font-size: 14px;
	font-weight: bold;
	text-transform: uppercase;
	color: #da4500;
}
.news_h1 {
	font-family: Arial, Helvetica, sans-serif;
	font-size: 18px;
	font-weight: bold;
	text-transform: uppercase;
	color: #da4500;
}

.Book_link {
	font-size: 12px;
	font-weight: bold;
}


hr {
    border:none;
    color: #ccc;
    background-color: #ccc;
    height: 1px;
    width:100%;
    clear:both;
}
.ul_1 {
	font-family: Verdana, Arial, Helvetica, sans-serif;
	font-size: 11px;
	font-weight: bold;
	padding: 15px 10px 10px;
	margin-top: 0px;
	margin-right: 0px;
	margin-bottom: 0px;
	margin-left: 0px;
	list-style-image: url('/i/bullet.gif');
}

.ul_1 li {
	
	padding-bottom: 5px ;

}
.ul_2 {
	font-family: Verdana, Arial, Helvetica, sans-serif;
	font-size: 11px;
	padding: 15px 10px 10px;
	margin-top: 0px;
	margin-right: 0px;
	margin-bottom: 0px;
	margin-left: 0px;
	list-style-image: url('/i/bullet.gif');
}

.ul_2 li {
	
	padding-bottom: 5px ;

}


.ul_3 {
	font-family: Verdana, Arial, Helvetica, sans-serif;
	font-size: 11px;
	padding: 5px 20px 0px;
	margin-top: 0px;
	margin-right: 0px;
	margin-bottom: 0px;
	margin-left: 0px;
	list-style-image: url('/i/bullet.gif');
}

.ul_3 li {
	
	padding-bottom: 2px ;

}



.right_content {
	padding-top: 22px;
	padding-right: 14px;
	padding-bottom: 30px;
	padding-left: 14px;
}
.news_h2_black {

	font-family: Arial, Helvetica, sans-serif;
	font-size: 14px;
	font-weight: bold;
	color: #333333;
}
.otziv {
	margin: 10px;
	text-align:justify;
}
.busket {
	padding-top: 5px;
	padding-right: 0px;
	padding-bottom: 5px;
	padding-left: 10px;
}
.b_zag {
	font-family: tahoma;
	font-size: 12px;
	font-weight: bold;
	color: #19509c;
}
.small {
	font-size: 10px;
}

.small2 {
	font-size: 9px;
}

/* menu nav states */
.hideSwitch {
    display:none;
}

.showSwitch {
    display:block;
}

.rollup {
    padding-left:18px!important;
    background:#ffffff  no-repeat 6px;
}

/*    background:#ffffff url(/i/bullet_menu.gif) no-repeat 6px;    */
.rolldown {
    padding-left:18px !important;
    background:#eff4f8 url('/i/bullet_menu_open.gif') no-repeat 6px;
}

.showtopic {
	font-size: 12px;
}

/* navigation
--------------------- */
div#netnav {
	float:left;
	font-family: tahoma;
	width: 200px;
}

#netnav * {
}

.netnav_1 {
    padding: 2px 0;
    border-bottom:1px solid #DAE5EE;
    text-transform:uppercase;
    cursor:pointer;
}

.netnav_22 {
    padding: 2px 0;
    background-color: #F3F4FF;
    border-bottom:1px solid #DAE5EE;
    text-transform:uppercase;
    cursor:pointer;
}


.netnav_active {
	padding: 2px 0;
	text-transform:uppercase;
	border: 1px solid #DAE5EE;
	background-image: url('/i/netnav.gif');
	background-repeat: repeat-x;
	background-position: top;
}

#netnav ul, #netnav li {
    margin:0;
    padding:0;
    list-style:none;
}

#netnav li {
    display:inline;
}


#netnav ul li a {
    text-decoration:none;
    display:block;
    margin:0;
    padding:6px 0px;
    color:#004191;
    border-bottom:1px solid #dae5ee;
}

#netnav ul ul li a {
	color:#666666;
	padding-left: 18px;
}

#netnav ul li a:hover {
	background-color:#eff4f8;
	color: #DA4500;
	font-weight: bold;
}


td.series_h {
    text-decoration:none;
    display:block;
    margin:0;
    padding:6px 0px;
    border-bottom:1px solid #dae5ee;
    font-weight: bold;
    background-color:#eff4f8;
    color: #DA4500;
}
td.series {
    text-decoration:none;
    display:block;
    margin:0;
    padding:6px 0px;
    color:#004191;
    border-bottom:1px solid #dae5ee;
}

#netnav a.selected {
   background-color:#ececec;
}

#search label {
    text-transform:uppercase;
}

.pngimg {behavior: url("/png.htc");}


.rubrikator {
	float: left;
	padding-right: 0px;
	padding-bottom: 12px;
}
.book_data {
	margin:3px 3px 3px 3px;
}
.hr_not {
    clear:none;
}
.small3 {
	font-size: 10px;
	font-family: tahoma;
}
.book_name {
	font-family: Arial, Helvetica, sans-serif;
	font-size: 20px;
	color: #333333;
	font-weight: bold;
}
.best {
	z-index: 200;
	visibility: visible;
	top: -50px;
	position: relative;
	width: 160px;
	clip: rect(auto, auto, -50px, auto);
	vertical-align: top;
}
.price,.sheader {
	font-family: arial;
	font-size: 20px;
	color: #004191;
	font-weight: bold;
}

.price_red {
	font-family: arial;
	font-size: 16px;
	color: red;
	font-weight: normal;
	text-decoration:line-through;
}
.subsmall {
	font-size:11px;
	cursor:pointer;
}

h1 {
	font-family: Arial, Helvetica, sans-serif;
	font-size: 20px;
}

h2 {
	font-family: Arial, Helvetica, sans-serif;
	font-size: 18px;
}


.areatitle {
	font-family: Arial, Helvetica, sans-serif;
	font-size: 14px;
	font-weight: bold;
}


h3 {
	font-family: Arial, Helvetica, sans-serif;
	font-size: 14px;
}
.text {
	font-size: 12px;
	line-height: 1.3em;
}
.sales {
	font-size: 14px;
}

.redprice {
	font-size: 14px;
	color: red;
}

.ul_blue {
	font-family: Verdana, Arial, Helvetica, sans-serif;
	list-style-image: url('/i/bullet_blue.gif');
}
.h1_none {
	font-family: Arial, Helvetica, sans-serif;
	font-size: 20px;
	font-weight: bold;
	color: #da4500;
}

a.h1 {
 color:#da4500;
 text-decoration:none; 
}

a.h1:hover {
 color:#da4500;
 text-decoration:none; 
}

a.h1:visited {
 color:#da4500;
 text-decoration:none; 
}


.style1 {color: #990000;}
.style1text {
 color: #990000;
 font-size: 12px;
 line-height: 1.3em;
}
.style4 {	color: #990000;    font-weight: bold;}

.opin_date {
	font-size:11px;
	color:gray;
}
.opin_hmm {
	margin: 5px 0px 5px 10px;
	text-align:justify;
	color:#5B5B5B;
	font-style:italic;
}
.opin_container {
	margin-top:25px;
}
.opin_answ {
	margin: 5px 0px 5px 25px;
	color:navy;
	text-align:justify;
}
.stamp {
	position:absolute;
	z-index:100;
	left:-10px;
	top:-15px;
	width:101px;
}
.stamp_outer {
	position:relative;
	width:183px;
}
.stamp_small {
	position:absolute;
	z-index:100;
	right:-40px;
	top:-5px;
	width:34px;
}
.stamp_outer_small {
	position:relative;
	width:34px;
}
.monospace {
	letter-spacing:2px;
	font-weight:bold;
	font-size:10px;
}
.fe {
	width:98%;
	border:solid gray 1px;
}
.cover_big_shadow {
	padding:0px 18px 0px 0px;
	background-image:url('/i/book_sh_big.jpg');
	background-position: 100% 100%;
	background-repeat:no-repeat;
	text-align:right;
}
.cover_small_shadow {
	padding:0px 13px 0px 0px;
	background-image:url('/i/book_s_shadow.gif');
	background-position: 100% 100%;
	background-repeat:no-repeat;
	text-align:right;
}
.cover_big {
	border: 1px solid #C8C8C8;
	border-right: 0px;
}
.cover_small {
	border: 1px solid silver;
	border-right: 0px;
}
.att_ico {
	display:none;
	margin-top:5px;
}
.att_lnk {
	font-weight:normal;
	cursor:pointer;
	color:#004191;
	letter-spacing:2px;
	font-size:10px;
	margin-top:5px;
}
.att_lnk:hover {
	text-decoration:underline;
}
.fl {
	float:left;
}
.fr {
	float:right;
}
.att_cont {
	margin-left:12px;
}
.splitter {
	margin:8px 0px 8px 0px;
}
.search_book_tbl {
}
.search_book_tbl td {
	vertical-align:top;
}
.projectMenuItem {
	padding-left:10px;
	text-align:left;
	background-image:url('/i/pr_menu_item.gif');
	background-repeat:no-repeat;
	background-position:0px 0px;
	margin-bottom:3px;
	width:198px;
	height:28px;
}
.projectMenuItem a:link, .projectMenuItem a:visited, .projectMenuItem a:active {
	color:#EBF2FC;
	font-weight:bold;
	text-decoration:none;
	font-size:10px;
}
.projectMenuItem a:hover {
	color:#EBF2FC;
	font-weight:bold;
	text-decoration:underline;
	font-size:10px;
}
.news_date {
	font-size: 11px;
	color:gray;
	text-decoration:underline;
}
.news_title {
	font-size: 12px;
	font-weight: bold;
}
.news_text {
	font-size: 12px;
	line-height: 1.3em;
}

.searchMatches {
	background:#88B4EF;
	color:white;
	font-weight:bold;
}

.a {background: url('lin.gif') repeat-x bottom; width:98%;}
.a .b {background: white; padding-right:2px;}
.a .c {background: white; padding-left:2px; position:absolute; right:2%;}
------------wOCwWjjIy35ybHEPCvEFB0
Content-Disposition: inline; filename=common_utils.js
Content-Type: application/javascript; charset=windows-1251; name=common_utils.js
Content-Location: http://www.piter-press.ru/js/common_utils.js?b=111
Content-Transfer-Encoding: Base64

ZnVuY3Rpb24gY29tbW9uVXRpbHMoKSB7DQoJLy8g7/Dl5OLg8Ojy5ev87eD/IO/u
5OPw8+fq4CDo5+7h8ODm5e3o6Q0KCXRoaXMuUHJlbG9hZEltYWdlcyA9IGZ1bmN0
aW9uKCkgew0KCQlpZiAoZG9jdW1lbnQuaW1hZ2VzKSB7DQoJCQlpZiAoYXJndW1l
bnRzLmxlbmd0aCA+IDApIHsNCgkJCQlmb3IgKHZhciBpPTA7aSA8IGFyZ3VtZW50
cy5sZW5ndGg7aSsrKSB7DQoJCQkJCWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lt
ZycpLnNldEF0dHJpYnV0ZSgnc3JjJyxhcmd1bWVudHNbaV0pOw0KCQkJCX0NCgkJ
CX0NCgkJfQ0KCX07DQoJLy8g7+7r8/fg5fIg8evl5PP++ejpIOfgIODw4/Ps5e3y
7uwg7eXy5erx8u7i++kg/evl7OXt8g0KCXRoaXMubmV4dE5vZGUgPSBmdW5jdGlv
bihlKSB7DQoJCXJldHVybiAoKGUgJiYgZS5ub2RlVHlwZSAhPSAxKSA/IG5leHRO
b2RlKGUgPSBlLm5leHRTaWJsaW5nKSA6IGUpOw0KCX07DQoJLy8g7u/w5eTl6+Xt
6OUg8erw7uvr6O3j4A0KCXRoaXMud2luZG93U2Nyb2xsID0gZnVuY3Rpb24oKSB7
DQoJCXZhciB4PTA7DQoJCXZhciB5PTA7DQoJCS8vIO7h+ejpIPHo7fLg6vHo8QkN
CgkJaWYgKHNlbGYucGFnZVhPZmZzZXQpIHsJDQoJCQl4ID0gc2VsZi5wYWdlWE9m
ZnNldDsJDQoJCQl5ID0gc2VsZi5wYWdlWU9mZnNldDsJDQoJCS8vIElFIDYgU3Ry
aWN0IE1vZGUJDQoJCX0gZWxzZSBpZiAoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50
ICYmIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQpIHsJDQoJ
CQl4ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbExlZnQ7DQoJCQl5
ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcDsNCgkJLy8gzvHy
4Ov87fvlIOLl8PHo6CBJRQkNCgkJfSBlbHNlIGlmIChkb2N1bWVudC5ib2R5KSB7
CQ0KCQkJeCA9IGRvY3VtZW50LmJvZHkuc2Nyb2xsTGVmdDsJDQoJCQl5ID0gZG9j
dW1lbnQuYm9keS5zY3JvbGxUb3A7CQ0KCQl9DQoJCXJldHVybiB7eDp4LHk6eX07
DQoJfTsNCgkvLyDu7/Dl5OXr5e3o5SDw4Ofs5fDu4iDu6u3gDQoJdGhpcy53aW5k
b3dTaXplID0gZnVuY3Rpb24oKSB7DQoJCXZhciB4PTA7DQoJCXZhciB5PTA7DQoJ
CS8vIO7h+ejpIPHo7fLg6vHo8QkNCgkJaWYgKHNlbGYuaW5uZXJIZWlnaHQpIHsJ
DQoJCQl4ID0gc2VsZi5pbm5lcldpZHRoOwkNCgkJCXkgPSBzZWxmLmlubmVySGVp
Z2h0OwkNCgkJLy8gSUUgNiBTdHJpY3QgTW9kZQkNCgkJfSBlbHNlIGlmIChkb2N1
bWVudC5kb2N1bWVudEVsZW1lbnQgJiYgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50
LmNsaWVudEhlaWdodCkgewkNCgkJCXggPSBkb2N1bWVudC5kb2N1bWVudEVsZW1l
bnQuY2xpZW50V2lkdGg7CQ0KCQkJeSA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVu
dC5jbGllbnRIZWlnaHQ7CQ0KCQkvLyDO8fLg6/zt++Ug4uXw8ejoIElFCQ0KCQl9
IGVsc2UgaWYgKGRvY3VtZW50LmJvZHkpIHsJDQoJCQl4ID0gZG9jdW1lbnQuYm9k
eS5jbGllbnRXaWR0aDsJDQoJCQl5ID0gZG9jdW1lbnQuYm9keS5jbGllbnRIZWln
aHQ7CQ0KCQl9DQoJCXJldHVybiB7eDp4LHk6eX07DQoJfTsNCgkvLyDv7ufo9uj/
IP3r5ezl7fLgIO3gIPHy8ODt6PblDQoJdGhpcy5lbFBvcyA9IGZ1bmN0aW9uKGVs
KSB7DQoJCXZhciB0b3A9MCxsZWZ0PTA7DQoJCXdoaWxlIChlbCkgew0KCQkJbGVm
dCArPSBlbC5vZmZzZXRMZWZ0IHx8IDA7DQoJCQl0b3AgKz0gZWwub2Zmc2V0VG9w
IHx8IDA7DQoJCQllbCA9IGVsLm9mZnNldFBhcmVudDsNCgkJfQ0KCQlyZXR1cm4g
e3g6bGVmdCx5OnRvcH07DQoJfTsNCgkvLyDz8fLg7eDi6+ji4OXyIPjo8Ojt8yDo
IOL78e7y8yD96+Xs5e3y4A0KCXRoaXMuc2V0RGltZW5zID0gZnVuY3Rpb24oZWws
eCx5KSB7DQoJCWlmIChlbCkgew0KCQkJCWVsLnN0eWxlLndpZHRoPXgrJ3B4JzsN
CgkJCQllbC5zdHlsZS5oZWlnaHQ9eSsncHgnOw0KCQl9DQoJfTsNCgkvLyDh6O3k
ID0pDQoJdGhpcy5iaW5kID0gZnVuY3Rpb24odG9PYmplY3QsbWV0aG9kTmFtZSkg
ew0KCSAgICByZXR1cm4gZnVuY3Rpb24oZSl7dG9PYmplY3RbbWV0aG9kTmFtZV0o
ZSl9DQoJfTsNCgkvLyDt4Oft4Pfg5fIg/evl7OXt8vMg8e7h+/Lo5Q0KCXRoaXMu
bGlzdGVuID0gZnVuY3Rpb24gKG9iamVjdCxoZXZlbnQsaGZ1bmMpIHsNCgkJaWYg
KG9iamVjdC5hZGRFdmVudExpc3RlbmVyKQ0KCQkJb2JqZWN0LmFkZEV2ZW50TGlz
dGVuZXIoaGV2ZW50LGhmdW5jLGZhbHNlKTsNCgkJZWxzZSBpZiAob2JqZWN0LmF0
dGFjaEV2ZW50KQ0KCQkJb2JqZWN0LmF0dGFjaEV2ZW50KCdvbicraGV2ZW50LGhm
dW5jKTsNCgl9Ow0KCS8vIO736Png5fIg/evl7OXt8iDu8iDi8eX1IOTu9+Xw7ej1
DQoJdGhpcy5lbXB0eUVsID0gZnVuY3Rpb24oZWwpIHsNCgkJaWYgKGVsKSB7DQoJ
CQl3aGlsZSAoZWwuZmlyc3RDaGlsZCkgew0KCQkJCWVsLnJlbW92ZUNoaWxkKGVs
LmZpcnN0Q2hpbGQpDQoJCQl9DQoJCX0NCgkJcmV0dXJuIGVsOw0KCX07DQp9

------------wOCwWjjIy35ybHEPCvEFB0
Content-Disposition: inline; filename=engine.js
Content-Type: application/javascript; name=engine.js
Content-Location: http://www.piter-press.ru/engine.js?b=111
Content-Transfer-Encoding: Base64

[encoded data, 17216 characters]
Cg==

------------wOCwWjjIy35ybHEPCvEFB0
Content-Disposition: inline; filename=1-1.gif
Content-Type: image/gif; name=1-1.gif
Content-Location: http://www.piter-press.ru/contents/978580460053/1-1.gif
Content-Transfer-Encoding: Base64

[encoded data, 7932 characters]

------------wOCwWjjIy35ybHEPCvEFB0
Content-Disposition: inline; filename=1-2.gif
Content-Type: image/gif; name=1-2.gif
Content-Location: http://www.piter-press.ru/contents/978580460053/1-2.gif
Content-Transfer-Encoding: Base64

[encoded data, 10752 characters]
fGlMZ1rTm+Z0pz39aVAjNiAAOw==

------------wOCwWjjIy35ybHEPCvEFB0
Content-Disposition: inline; filename=1-3.gif
Content-Type: image/gif; name=1-3.gif
Content-Location: http://www.piter-press.ru/contents/978580460053/1-3.gif
Content-Transfer-Encoding: Base64

[encoded data, 8064 characters]
3/gc6/iQfydPH/mU3xODf/mYn/mav/mc3/kRERAAOw==

------------wOCwWjjIy35ybHEPCvEFB0
Content-Disposition: inline; filename=1-4.gif
Content-Type: image/gif; name=1-4.gif
Content-Location: http://www.piter-press.ru/contents/978580460053/1-4.gif
Content-Transfer-Encoding: Base64

[encoded data, 10816 characters]
OtSs5nWvRTxkTdML2I9k1LC7zCoQJ1vZy2Z2s539bGhHO8MBAQA7

------------wOCwWjjIy35ybHEPCvEFB0
Content-Disposition: inline; filename=1-5.gif
Content-Type: image/gif; name=1-5.gif
Content-Location: http://www.piter-press.ru/contents/978580460053/1-5.gif
Content-Transfer-Encoding: Base64

[encoded data, 11648 characters]
nEM6RK6AAAA7

------------wOCwWjjIy35ybHEPCvEFB0
Content-Disposition: inline; filename=1-6.gif
Content-Type: image/gif; name=1-6.gif
Content-Location: http://www.piter-press.ru/contents/978580460053/1-6.gif
Content-Transfer-Encoding: Base64

R0lGODlh9AErAfcAAP////7+/v39/fz8/Pv7+/r6+vn5+fj4+Pf39/b29vX19fT0
9PPz8/Ly8vHx8fDw8O/v7+7u7u3t7ezs7Ovr6+rq6unp6ejo6Ofn5+bm5uXl5eTk
5OPj4+Li4uHh4eDg4N/f397e3t3d3dzc3Nvb29ra2tnZ2djY2NfX19bW1tXV1dTU
1NPT09LS0tHR0dDQ0M/Pz87Ozs3NzczMzMvLy8rKysnJycjIyMfHx8bGxsXFxcTE
xMPDw8LCwsHBwcDAwL+/v76+vr29vby8vLu7u7q6urm5ubi4uLe3t7a2trW1tbS0
tLOzs7KysrGxsbCwsK+vr66urq2traysrKurq6qqqqmpqaioqKenp6ampqWlpaSk
pKOjo6KioqGhoaCgoJ+fn56enp2dnZycnJubm5qampmZmZiYmJeXl5aWlpWVlZSU
lJOTk5KSkpGRkZCQkI+Pj46Ojo2NjYyMjIuLi4qKiomJiYiIiIeHh4aGhoWFhYSE
hIODg4KCgoGBgYCAgH9/f35+fn19fXx8fHt7e3p6enl5eXh4eHd3d3Z2dnV1dXR0
dHNzc3JycnFxcXBwcG9vb25ubm1tbWxsbGtra2pqamlpaWhoaGdnZ2ZmZmVlZWRk
ZGNjY2JiYmFhYWBgYF9fX15eXl1dXVxcXFtbW1paWllZWVhYWFdXV1ZWVlVVVVRU
VFNTU1JSUlFRUVBQUE9PT05OTk1NTUxMTEtLS0pKSklJSUhISEdHR0ZGRkVFRURE
RENDQ0JCQkFBQUBAQD8/Pz4+Pj09PTw8PDs7Ozo6Ojk5OTg4ODc3NzY2NjU1NTQ0
NDMzMzIyMjExMTAwMC8vLy4uLi0tLSwsLCsrKyoqKikpKSgoKCcnJyYmJiUlJSQk
JCMjIyIiIiEhISAgIB8fHx4eHh0dHRwcHBsbGxoaGhkZGRgYGBcXFxYWFhUVFRQU
FBMTExISEhERERAQEA8PDw4ODg0NDQwMDAsLCwoKCgkJCQgICAcHBwYGBgUFBQQE
BAMDAwICAgEBAQAAACwAAAAA9AErAQAI/wD/CRxIsKDBgwgTKlzIsKHDhxAjSpxI
saLFixgzatzIsaPHjwWBiBxJsqTJkyhTqlzJsqXLlzBjypxJs6bNmzhz6tzJs6fP
nyIFAplHtKjRo0iTKl3KtKnTp1CjSp1KtarVq1izat3KtavXr2DDAhFK9N+Pf/P+
vUn74wvasHDjyp1Lt67du3jz6t07b+y/oWmL/Jr36s2/MmnL8V3MuLHjx5AjS24K
AITly5gBVcbMGQTazZ0tAyLqF/A/KGv+PTFcRuDk17Bjy55NWzIAlZpBqPyMmzTZ
tFBWlQFlGNy8Wt+KAgAgdXnt59CjS5+++HbK3H5Djp1nHeXovr//bf/6t+7fqn+/
IEF6u7y9c/fc28d3Tr2+/fv48yftfhL7X5L/8VbagN+VRtQzs8xCDT2xuFOHBhrI
oxxz8c1HFIUYUqjfhhx26KFj/JnkX0kBcjcSQSMV+BuC2eTSjT0nFJHWdhVWSB93
R9344Y489ugjViGWNCKAQZl44n8iqfjXgbPMs4s751DTyy7CvFXjexoqd2GWP3bp
5Zc/BknSkCcW2R2KSfq25DwIzuNMOeek5QwoGky4ZY1GZQjmnnz2iZ912gFBZlBm
BhXgf0oChuA/0yyzDxYa+POPBuzpeSN8d/qp6aac2oZbZbsZ6Z2aiiY4yy3pROIB
hCNY2emrsMb/KpuYKYKakoCjgrdmNrxmEw845FDDCCO3yGrsscgullFaC5Ga7LPQ
RvvjgEBVa+212Gar7bbcduvtt+AaKihI5JZr7rnopqvuuuy26667INwmFCDv1mvv
vfjmq+++/PaLULyl0bvFFgIRfNDABu+LsL8MN+zwwxBHXBHA8/4zcMEJXVyuxg0l
nLDEIIcs8sgkm0vxXwIb/HFBHIPU8kIelyzzzDTXbLNAJ4+rsccft7xwwTsTzPPK
BCHMc8YHs3zz0kw37XS5OacstMUqD8TxyjFPPTXGCF0NdNJFG031z0+XbfbZaBcU
9dgWU82122+/rXXbMXdd98txW6102nz3/+03zWvTLTTRXhet99xEH3x34nX/7fjj
kIcc+OBcH/31zm3TnXnVdlu9ddKJRy766KTDKy/KGF8dtOpDyw003mF7rhDZpddu
++0fBY777rz3/rjuvgcv/PA2ry22w6FHDDvxzDfPkfGcM5w8RMtvVL3z2Gd/EfR5
8zv9Q9dnFL725JfPEPeCw63+8WzbfTH70e+9Oebdv265+56rTPbx+2fuv/7fM58A
a8e99/GvcpfT2+zcRr/QRW9rjTOI6vwnQQTqb309O9oDUzfADvoOfV8zHAOxBrOF
NbB+mnNdBFm2OLApMH3/y6AC33e4F3rwhqUDofrq5zMHHo5z8QvbCv9hqLgZMk5+
lIth7Cr3uc/h8Ik5PJ3OZChCCZKwgqkDIgqTSLgdstCILlThA6k4v/9REIpohJwO
8fYz+FWPhvTzYhUBWMWM3U9xrYMbFQ+oRwiOL42AZBrw7hXAEj7NPcsJpCIFKUV6
LfKRkMTdICNJyUr6bZKWzKQmm4bJTXrykyTrJChHScqGibKUqEylvU6pyla68lys
fKUsZ6mRWNLylriEiC1zycteGmSXvgwmL4EpzGLOkpjGTKYqkanMZo6Smc6Mpiah
Kc1qRpKa1sxmILGpzW4+kZveDOcAwSnOcmqPnOZMJ/PQqc52frCR7ownFNkpz3qS
jp72zOfv4Kn/z35iD5/+DKjZACrQgjIyYAZN6O4IqtCGhpKfDo2oGiEq0Yr2jaEW
zWi/MKrRjuKLox4NqekQKtKS1gykJk0p1Ciq0pZGDKUujWlGYCrTmlKEpjbN6UNw
qtOeKoSnPg2q2lgq1KKajKhGTapHgKrUnjK1qTl9KlRrKtWpxrSqVm0pVrOa0q1y
taRe/WpIwyrWjpK1rBk9K1orqta1RrStbm0oXOOa0LnStaB2vWtA86rXfvK1r/n8
K2DrKdjBxrOwhm0nYhObzsUytpyOfWw4IyvZblK2stm8LGarqdnNRrOznm0maEOb
zNGStpimPW0wU6vaXrK2tbl8LWxvKdvZ/x4Tqba1aW1z68rd8naZuP2tS30r3FIS
t7jPDC5yTXrc5Xqyuc6dpnKj61HoUreS1r3uNaerXYtmt7uL/C54t8nd8TpUvOZF
I3rT+83ysteg632vB+Mr33G6t77+pC9+y6ff/Z7zvv61Z38D7LwBE3idAD6wOw2s
YOExuMHvJCmE8ZrgCUO2whaeLIYzbNkNczizHv4wZ0Ms4s+SuMSiPTGKS6viFaO2
xS5eLYxj7NoZ0zi2Nr4xbXOs49tKuMcX/jGQNSzkIXe4yEYGMZKTPOIlM9nETn5y
iqMsZRZTucovvjKWZazlLde4y17GMZjDvOMxk9nHFTvzlNOsZiuzuf/NWX4znLks
5zl/uc52FjOe81zmPfMZzaj7850DLWg9E7rQfT40ogE9rkUnutGOZrQjIy3LB1Pa
YZa+NMMyremN8rjTHeQ0qPUl6lF/9NOm5i+qU/1fM7OavK5+dRpLLet20brW67o1
rtOl613DctW+djCwgx1hPxMb1sY+9qyHrWxJMrvZtus1tJ/37Gnfs9rWFp20s42R
bXPbIt7+9k2xLe6/hbvcETk3undK7nWnTd3uPl+74z3QedP7afC+97/sre+DJrvf
xMs3wAki8IHjjN8GBxzCEy6zghvc4QOHOMAl3m+K69vi98Y4vTUeb4672+PrBjm6
RV5ukovb5N/gRjm3VZ5tllvb5dOGObRl3myaK9vmx8Y5sXUebJ772ue7BjquhV5r
osva6K9GOquVnmqmm9rpo4Y6qKXeaapr2uqXxjqltR5prjva64sGO6LFXmiyC9rs
f0Y7n9WeZ7bb2e1zhjuc5d5muqvZ7mfGO5n1Hma+e9nvWwY8lgVf5aiF5vCIT7zi
F8/4xjv+8ZCPvOQnT/nKW/7ymM+85jfP+c57XvJSRKToR0/60pv+9KhPvepXz/rW
u/71sI+97GdP+9rb/va4z73ud296aoXr98APvvCHT/ziG//4DL9hQAAAOw==

------------wOCwWjjIy35ybHEPCvEFB0
Content-Disposition: inline; filename=1-7.gif
Content-Type: image/gif; name=1-7.gif
Content-Location: http://www.piter-press.ru/contents/978580460053/1-7.gif
Content-Transfer-Encoding: Base64

[encoded data, 4736 characters]
kRRZkRZ5kRiZkRq5kZnYRwEBADs=

------------wOCwWjjIy35ybHEPCvEFB0
Content-Disposition: inline; filename=1-8.gif
Content-Type: image/gif; name=1-8.gif
Content-Location: http://www.piter-press.ru/contents/978580460053/1-8.gif
Content-Transfer-Encoding: Base64

[encoded data, 4800 characters]
TQEBADs=

------------wOCwWjjIy35ybHEPCvEFB0
Content-Disposition: inline; filename=1-9.gif
Content-Type: image/gif; name=1-9.gif
Content-Location: http://www.piter-press.ru/contents/978580460053/1-9.gif
Content-Transfer-Encoding: Base64

[encoded data, 4160 characters]
50//+ttf5QMMCAA7

------------wOCwWjjIy35ybHEPCvEFB0
Content-Disposition: inline; filename=1-10.gif
Content-Type: image/gif; name=1-10.gif
Content-Location: http://www.piter-press.ru/contents/978580460053/1-10.gif
Content-Transfer-Encoding: Base64

R0lGODlh9AErAfcAAP////7+/v39/fz8/Pv7+/r6+vn5+fj4+Pf39/b29vX19fT0
9PPz8/Ly8vHx8fDw8O/v7+7u7u3t7ezs7Ovr6+rq6unp6ejo6Ofn5+bm5uXl5eTk
5OPj4+Li4uHh4eDg4N/f397e3t3d3dzc3Nvb29ra2tnZ2djY2NfX19bW1tXV1dTU
1NPT09LS0tHR0dDQ0M/Pz87Ozs3NzczMzMvLy8rKysnJycjIyMfHx8bGxsXFxcTE
xMPDw8LCwsHBwcDAwL+/v76+vr29vby8vLu7u7q6urm5ubi4uLe3t7a2trW1tbS0
tLOzs7KysrGxsbCwsK+vr66urq2traysrKurq6qqqqmpqaioqKenp6ampqWlpaSk
pKOjo6KioqGhoaCgoJ+fn56enp2dnZycnJubm5qampmZmZiYmJeXl5aWlpWVlZSU
lJOTk5KSkpGRkZCQkI+Pj46Ojo2NjYyMjIuLi4qKiomJiYiIiIeHh4aGhoWFhYSE
hIODg4KCgoGBgYCAgH9/f35+fn19fXx8fHt7e3p6enl5eXh4eHd3d3Z2dnV1dXR0
dHNzc3JycnFxcXBwcG9vb25ubm1tbWxsbGtra2pqamlpaWhoaGdnZ2ZmZmVlZWRk
ZGNjY2JiYmFhYWBgYF9fX15eXl1dXVxcXFtbW1paWllZWVhYWFdXV1ZWVlVVVVRU
VFNTU1JSUlFRUVBQUE9PT05OTk1NTUxMTEtLS0pKSklJSUhISEdHR0ZGRkVFRURE
RENDQ0JCQkFBQUBAQD8/Pz4+Pj09PTw8PDs7Ozo6Ojk5OTg4ODc3NzY2NjU1NTQ0
NDMzMzIyMjExMTAwMC8vLy4uLi0tLSwsLCsrKyoqKikpKSgoKCcnJyYmJiUlJSQk
JCMjIyIiIiEhISAgIB8fHx4eHh0dHRwcHBsbGxoaGhkZGRgYGBcXFxYWFhUVFRQU
FBMTExISEhERERAQEA8PDw4ODg0NDQwMDAsLCwoKCgkJCQgICAcHBwYGBgUFBQQE
BAMDAwICAgEBAQAAACwAAAAA9AErAQAI/wD/CRxIsKDBgwgTKlzIsKHDhxAjSpxI
saLFixgzatzIsaPHjwWBiBxJsqTJkyhTqlzJsqXLlzBjypxJs6bNmzhz6tzJs6fP
nyIFAplHtKjRo0iTKl3KtKnTp1CjSp1KtarVq1izat3KtavXr2DDAhFK9N+Pf/P+
vUn74wvasHDjyp1Lt67du3jz6t07b+y/oWmL/Jr36s2/MmnL8V3MuLHjx5AjS24K
AITly5gBVcbMGQTazZ0tAyLqF/A/KGv+PTFcRuDk17Bjy55NWzIAlZpBqPyMmzTZ
tFBWlQFlGNy8Wt+4AgBQlXnt59CjS5/eHHdlvyHHzrudcnTf3/82/f9b92/Vv1+Q
IL0lutz5cvbM2xdtLx++8+318b/fbv++fv/UBSjggATKxR1KuY1V0l/acSdUaUB4
VxpRz8wyCzX0xOJOHRpoIM988YUI338j4tdfie+l6N6I+6lY4IswxijjUweelCCD
IzHIW1ADjSThbxVmk0s39pxQRFramcgffy6a2KKISoKo5IpOQrnfjFhmqSV1NZp0
44JBbUfSgyL9+BeFs8yzizvnUNPLLsKs16J9JUpZJYvuWckenlMCuOWfgAbaWJcl
fTlmmAcS5KNvZ85T4TzOlHNOWs6AooGd9z3J552cNkmli5oKKuqopM7loKJlXodj
UIjy6GqEjAL/VuE/0yyzDxYa+POPBnJeGWV+oeoHYn307ckpiaUmq+yy1XV3XUo7
Ihgrmhbekk4kHnQ4wnq0+crst+CGSyhJCUIrZnfTzpPNutnEAw451DDCyC3R+Rnu
vfiKmlFaC6Wb778AB3wvhEAVbPDBCCes8MIMN+zwwxC7CghIFFds8cUYZ6zxxhx3
7LHHINwm1MQfl2zyySinrPLKLLd8UMilTbzFFgbN7PLNOOes884892wRzCP/Y7PP
RBdt9NFIJ10x0H/JTLPSUEct9dRU88x0hELP/HTWW1ft9ddghy22Q1c7LdDWQ4+t
9tpst2102VmfPVDabtdt9914awz30Gh3/53334AHLnhDez/d9+CIJ67434XLzbXf
i0cu+eRQw0355ZhnXrnITWvu+eeg31w43S5D7jPpoaeu+kONC52z6RKh3pHsq9du
u0Ktw56y7hDRvpHvtwcffO5xp2281nP7rjXNy8/teM3Oc/087M2fzTvy1huO/ePZ
O4929NsLL/7gjdu8vOGOa+/68wgx73767U+//vftH647+q6rfzxB++M///rjCyDg
Wme9gujPb7zjHt/gdxDmRS9/D6wZ/WSHQO/5j27GK+D36CfADtqNgHHjXwO7RrsN
4s9/BsygAUM4QvCZroJyW2ABk+dCADrQgzi8GwhJRz0YrjCGJ2SfCP9lOMT7TfCF
P8zfBUl4RBsCMIdQXNsOIYe96kmvfkqc3v1cSEKG7C8h26siCvlWxRmar3tRTCPY
LLe7iwAvafRZjhrniDQ20vGOeGybHfPIxz5WbY9+DKQg38Y5rA3ykIi0WiFJlshG
OlJlgHykJCeJsUhS8pKY3IglM8nJTkZkk54MpShftshRmvKUpIwZKleJSlCy8pWS
dCUsZ4lIWdLyln60JS53eUdd8vKXUfQlMIfZQWES85jCMyYyl7k6ZTLzmZ9zJjSn
eTlpUvOai7MmNrcpOG1y85t48yY4x6nHUpLznJMTJzrX6TV1svOdUXMnPOd5NHnS
8549syc+94n/M33y858r8ydAB2oygRL0oBwzKEIXejGFMvShH3EoRCeqEYlS9KIV
sShGNwoRjXL0owvxKEhHahCRkvSk/zApSkeq0pV+tKUu3ShMY3rRmdJ0oja96UNz
qtOF8rSnB/0pUAcq1KH+s6hG3SdSk3rPpTJ1nk596jujKtV1UrWq57wqVsep1a1+
s6te3SZYw3rNsZJ1mmY96zPTqtZlsrWtx3wrXIcp17n+sq523SVe83rLvfJ1ln79
6ysDK9hVErawpzwsYkep2MWGsrGO7SRkI5vJyVL2kpa97CQzq9lHcrazjfwsaGtp
ztFyVLSmFSRqU5vL0rKWoqt9bR5jK9te/7q2tgylLW7VqNvdBvO2viVob4OLw+ES
t5jAPS4/javc8TG3uclMLnTp+dzp2q661m2mdLPLTuxyN3Te/W40tytecoa3vJk7
L3qrSd71clO97pUcfOObzfbSl5rzvS/i8qvfbtq3v8zkL4AZ998Bx7XABqYrghN8
1wUzWK8OfnBfIyxhwFK4woO9MIYNq+ENJ7bDHmYsiEP82BGTWLImPnFlU6xizLK4
xZt9MYw9K+MZh7bGNiatKnMM4R3zeMI+/rGFgyzkDBO5yBw+MpI/rOQli7jJTi4x
lKOM4ilTecVWvrKLs6zlGHO5yzT+MphvLOYx6zhoZvakgNPcTxyz2f+Da35zy+Is
54C6uc7OvTOeo1vmPeORzn4uqJ4DXTtAExpkgz506gyt6I0xutEZezSkG5roSWtO
0pamGKYzHdFKc5pym/40R0It6op6utT17TOq+YzmVdOR1K7O6Klj7V9V01q7tr71
omet67zButes4zWwPyjsYbvt18YOabGTLcVlM3tsyH52KlstbVZ3rtriiza2B6Lt
bafU2d6mWre3PW5sl7va55Z2up+9bma3O9nvNna8hz1vYNe71/fWdb5vvW9a9zvW
/3Z1wFc9cFQXvNQHF3XCP71wTjc80w+3dMQnPXFIV7zRF1d0xg+9cUJ3PNAf93PI
9zxyPJe8zie1l3PK37xyNrc8zS83c8zHPHMw17zLN9dyzq+8cyr3PMo/d3LQlzx0
JBe9yEcXctJ/vHQeNz3HT7dx1Gc8dRhXvcVXV3HWT7x1Enc9xF/3cNg3PHYMly00
aE+72tfO9ra7/e1wj7vc5073utv97njPu973zve++/3vcy9kHAdP+MIb/vCIT7zi
F8/4xjv+8ZCPvOQnT/nKW/7ymM+85jfP+cMTLGKgD73oR0/60pv+9KgPtwcDAgA7

------------wOCwWjjIy35ybHEPCvEFB0
Content-Disposition: inline; filename=piter.htm
Content-Type: text/html; charset=iso-8859-1; name=piter.htm
Content-Location: http://shop.piter.com/piter.ico
Content-Transfer-Encoding: 8bit

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /piter.ico was not found on this server.</p>
<hr>
<address>Apache/2.2.16 (Debian) Server at shop.piter.com Port 82</address>
</body></html>

------------wOCwWjjIy35ybHEPCvEFB0--
