
- •1.1. Что такое программа и как она выглядит?
- •1.2. Комментарии
- •1.3. Зарезервированные слова и типы данных
- •1.4. Объявление переменных
- •1.5. Операции и выражения
- •1.6. Ввод и вывод
- •1.7. Переменные и константы
- •1.8 Логические операторы
- •1.9. Управляющие операторы
- •1.10. Операторы циклов
- •1.11. Операторы перехода
- •2. Функции
- •2.1. Передача параметров
- •2.2. Библиотечные функции
- •2.3. Локальные и глобальные переменные
- •Объявления функций
- •Время жизни и область видимости программных объектов
- •Int local_var; /* по умолчанию auto */
- •2.4. Перегрузка
- •Виртуальный метод
- •3. Массивы
- •Перечисления
- •Объединения
- •858993459 //Результат будет неопределенным,
- •Множества
- •4. Структуры
- •Int numberPeriod; //число переодов начисления процентов
- •Int page; //Количество страниц
- •Void print(); /*Внимание, записывается только прототип функции */
- •Int yearBorn; //год рождения
- •Int yearBorn; //год рождения
- •4.1. Демонстрационные программы
- •Int done;/*переменная, которая информирует о конце списка файлов */
- •6. Объединения
- •Info;//Обявление переменной типа объединение
- •Info;//Обявление переменной типа объединение
- •7. Объектно-ориентированное программирование
- •7.1. Классы и объекты
- •Демонстрационные программы
- •Результат работы программы
- •7.2. Конструкторы и деструкторы
- •Конструктор копирования
- •Конструктор копирования
- •7.5. Наследование
- •7.3. Создание объектов и обращение к членам объекта
- •8. Абстрактные типы данных
- •9. Пространство имен
- •Void greeting();/*это пространство имен содержит функцию с тем же
- •Void big_greeting(); /*эта функция не попадает ни в одно из созданных подпространств,т.Е. Принадлежит пространству имен std */
- •//Определение функций
- •Void big_greeting() /* определение данной функции не принадлежит ни одному из созданных пространств имен, следовательно дальнейший код помещается в глобальное пространство имен */
- •10. Строки
- •4.3 Демонстрационные программы
- •4.10. Класс string
- •Класс AnsiString
- •Класс AnsiString
- •Класс Set
- •4.9. Перегрузка операторов
- •Использование "умных" указателей
- •4.8. Полиморфизм
- •Главное меню — компонент MainMenu
- •Диалоги
- •Файлы и потоки
- •Ввод-вывод в файл
- •Ifstream inStream; //Объявление входного потока
- •InStream.Open("character.Dat"); /*присоединение файла к входному потоку */
- •InStream.Close(); //закрытие входного потока
- •If(!out){ //при неудачной попытке
- •If(in.Fail()){ //поток не создан, то сообщение и выход
- •Управление потоком ввода-вывода
- •Дополнительные возможности cin и cout
- •Что внутри iostream.H
- •Использование cout
- •Использование символа-заполнителя
- •Управление цифрами значений с плавающей точкой
- •Вывод и ввод одного символа за один раз
- •Чтение ввода с клавиатуры по одному символу за раз
- •Чтение с клавиатуры целой строки
- •Что вам необходимо знать
- •5.2. Ввод имен файлов
- •5.3. Манипуляторы
- •5. Указатели
- •5.1.Типы указателей и операции с указателями
- •Адресная арифметика
- •Сравнение указателей
- •Преобразование типа указателя
- •Указатель void
- •5.2. Динамические массивы
- •Int array[10]; //объявляется массив с именем array
- •Int a[10]; //объявляется массив с именем a
- •Int *array1; //указатель типа int с именем array1
- •Int *array[5];/*массив с именем array, его элементы указатели*/
- •Int (*point)[4][5]; /*объявление указателя на двумерный массив без имени */
- •Использование указателей в функциях и указатели на функции
- •Указатель классов
- •Шаблоны
- •Шаблоны функций
- •Void Swap (t& X, t& y) /* к моменту обращения тип т будет известен и заменен, например, на int */
- •Void sort(t array[], int maxIndex){ /*передали массив и его размер */
- •6.2. Шаблоны классов
- •6.3 Демонстрационные программы
- •7.1 Обработка исключений
- •Исключения и их стандартная обработка
- •Базовый класс исключений vcl Exception
- •Упражнения
- •Обработка исключительных ситуаций, возбуждаемых оператором new
- •Исходные файлы и объявление переменных
- •Связанные списки
- •Void newHead(PtrNode& head, //адрес головного узла
- •Void newHead(PtrNode& head, //адрес головного узла
- •Поиск в связанных списках
- •Void newHead(PtrNode& head, //адрес головного узла
- •Директивы препроцессора.
- •Структура файла проекта
- •Структура make-файла
- •Структура модуля
- •Структура h-файла
- •Файл формы
- •Особенности программирования под Windows.
- •Создание окон.
- •Функция WinMain
- •Создание проекта Win32Application.
- •Библиотека mfc.
- •Создаем код
- •Шпаргалка
- •Структура файла проекта
- •Структура make-файла
- •Структура модуля
- •Структура h-файла
- •Файл формы
- •Файл проекта
- •Введение
- •Свойства компонентов
- •События
- •Менеджер проектов
- •Пример: создание простейшего приложения
- •Графика Внедрение картинок
- •Редактор изображений
- •Классы для хранения графических объектов.
- •If (SelectDirectory( //Компонент библиотеки
- •Методы создания собственной графики. Рисование по пикселам
- •Int px, py; //координаты пикселей
- •Рисование с помощью пера
- •Int px, py; //координаты пикселей
- •Рисование кистью
- •Мультимедиа и анимация Общие сведения о звуковых и видеофайлах
- •Способы воспроизведения звуков
- •Создание мультфильма
- •Воспроизведение немых видео клипов — компонент Animate
- •Проигрыватель MediaPlayer
- •Процессы, потоки, распределенные приложения
- •If include "uOverlayl.H" // включение головного файла приложения
- •Функция CrateProcess
- •Заключение
- •Что такое ansi?
- •Почему вместо русских букв в консольном приложении выводится мусор? Автор: Алексей Кирюшкин Версия текста: 1.0
- •Выход 1
- •Выход 2
- •Выход 3
- •Выход 4
- •Ввод-вывод файлов
- •Выбор компонентов для групповых операций
- •Установка разделяемых свойств компонентов
- •Изменение размера компонентов
- •Выравнивание компонентов
- •Пример: Создание текстового редактора Проектирование формы приложения
- •Создание обработчиков событий
- •Создание меню
Демонстрационные программы
Рассмотрим
интересный класс с названием стек. С
его помощью можно создать реальный
стек. Напомним, что стек это устройство,
работающее по принципу последним вошел
– первым вышел. Примером такого устройства
может являться детская игрушка –
пирамида, представляющая собой стержень
(stack)
на который надеваются кольца разного
диаметра. В этой игре первым со стека
снимается кольцо, которое было надето
последним. В нашей задаче, конечно, будет
использоваться стек для чисел.
#include <iostream>
using namespace std;
#include <windows.h>
#define SIZE 100 //размер стека
//Определение класса stack
class stack{
int stck[SIZE]; /*массив,в котором хранятся числа,
записанные в стек, это не сам стек */
int tos; //переменная показывающая заполнение стека
public:
void init(); //функция инициализации стека
void push(int i); //функция записи (протягивания) в стек
int pop(); //функция уменьшения указателя очереди
};
//------конец класса, далее идет описание функций -------------
void stack::init(){ //установка указателя номера на ноль
tos=0;
}
//----------------------------
void stack::push(int i){
if(tos==SIZE){
cout<<”Стек полон”<<endl;
return;} // return говорит об окончании выполнения кода функции
stck[tos]=i;
tos++;
}
//-----------------------------
int stack::pop(){
if(tos==0){
cout<<”Стек пуст”<<endl;
return 0;
}
tos--;
return stck[tos];
}
//-------------------------
int main(){
stack stack1, stack2; //Создаем объекты класса stack
stack1.init(); //Опустошаем стеки
stack2.init();
stack1.push(1);
stack2.push(2);
stack1.push(3);
stack2.push(4);
cout<<stack1.pop()<<” “;
cout<<stack1.pop()<<” “;
cout<<stack2.pop()<<” “;
cout<<stack2.pop()<<” “;
return 0;
}
Результат работы программы
3 1 4 2
т.е. числа из обоих стеков выходят в обратном порядке.
Попробуйте на базе данного примера создать программу в которой имеется два стека. Числа в стеки записываются с клавиатуры. Количество записаных чисел в каждый стек может быть разным.
7.2. Конструкторы и деструкторы
Теперь, когда мы имеем некоторое представление о классах и объектах, давайте задумаемся над тем, как задать начальные значения переменным класса. Например, имеется класс
class MyClass{
public:
int a,b,c;
void print();
};
void MyClass::print(){
cout<<”a=”<<a<<endl<<”b=”<<b<<endl<<”c=”<<c;
}
Нужно инициализировать переменные a,b,c.
Напомним, что класс состоит из объявлений и прототипов функций. Задать начальные значения переменных, т.е. написать, например,
int a=0,b=1,c=2;
нельзя, т.к. класс это некий шаблон кода в котором нельзя инициализировать переменные. Если попытаться запустить функцию print(), то на экране появятся случайные числа, оказавшиеся в выбранных компилятором ячейках памяти. Они остались там от предыдущей прграммы.
Если учесть что класс это тип данных то вопрос можно сформулировать так: как присвоить такому типу данных начальные значения? Можно конечно поступить так: создать объект, а потом вызвать его параметры через оператор точка. В данном случае это выглядит так:
MyClass mc;
mc.a=0; mc.b=1; mc.c=2;
Согласитесь, что это не очень удобно. Оказывается в С++ для этого предусмотрены специальные средства. Это так называемые конструкторы.
Конструктор это функция специального вида, которая используется для инициализации нескольких или всех переменных-членов, и для других инициализирующих действий. Скажем сразу, что программист может не создавать конструктор, но тогда сам компилятор автоматически создаст конструктор, который, правда, не выполняет никаких действий.
Отличие конструктора от функций состоит в следующем:
Имя конструктора должно совпадать с именем класса. Например, класс MyClass должен иметь конструкторMyClass().Правда, в рассмотренном примере его нет, в силу того, что он был создан автоматически или, как говорят, по умолчанию.
Конструктор не возвращает никакого значения.
В начале прототипа или в заголовке не должно присутствовать указание на какой либо тип, даже на void.
Конструктор должен находиься в секции public.
Рассмотрим простой пример программы выполняющей ввод и сложение двух чисел.
Таким образом рассмотренный приер класса должен выглядеть так:
#include <iostream.h>
class MyClass{
public:
int a,b,c;
MyClass();
void print();
};
void MyClass::print(){
cout<<”a=”<<a<<endl<<”b=”<<b<<endl<<”c=”<<c;
}
MyClass::MyClass(){
a=0,b=1,c=2;
}
Обратите внимание, что в описании класса также присутствует только прототип конструктора. Его описание производится также как и обычной функции, с той лишь разницей, что не указывается тип возвращаемой величины.
Как и любая функция, конструктор может иметь параметры или аргументы. Они могут быть использованы для инициализации. Возвращаясь к нашему примеру класс с конструктором, имеющим параметры можно записать так:
#include <iostream.h>
class MyClass{
public:
int a,b,c;
MyClass(int x,int y,int z);
void print();
};
void MyClass::print(){
cout<<"a="<<a<<endl<<"b="<<b<<endl<<"c="<<c;
}
MyClass::MyClass(int x,int y,int z){
a=x, b=y, c=z;
}
Работа программы с созданным классом может быть выглядеть так:
int main(){
MyClass mc(0,1,2);//создание объекта с инициализацией
mc.print();
char z;
cin>>z;
return 0;
}
Рассмотрим более сложный пример. Создадим класс для суммирования двух чисел, вводимых с клавиатуры.
//Программа суммирования двух чисел
#include <iostream>
using namespace std;
class Summa {
public:
double z;
Summa(double x,double y);
};
//описание конструктора
Summa::Summa (double x, double y){
z=x+y;
}
//------------
void main(){
double x,y;
cin>>x>>y;
Summa sum(x,y); /*объявление объекта класса Summa или
неявный вызов конструктора */
cout<<"\nRESULT="<<sum.z; /*переменная класса вызывается через
имя класса и имя переменной, разделенных точкой */
}
В рассмотренном примере был использован, так называемый неявный вызов конструктора. Здесь при объявлении объекта с именем sumуказаны его данные необходимые для конструктора.
Вместо строки
Summa sum(x,y);
можно было использовать явный вызов
Summa sum; //объявление объекта
sum= Summa(x,y); //инициализация
но этот способ инициализации некоторыми компиляторами не поддерживается.
Объявление можно совместить с инициализацией, подобно тому как это делается с базовыми переменными:
Summa sum=Summa(x,y);//объявление и инициализация
При объявлении объектов конструктор вызывается автоматически. Однако конструктор можно вызвать еще раз, подобно тому как это можно делать с обычной функцией. Конструктор должен быть открытым членом класса. Иначе к нему не будет доступа извне.
Заметим, что конструкторов может быть несколько, впрочем, как и функций с одним именем. Иначе говоря, конструктор может быть перегруженным. Для лучшего понимания сказанного рассмотрим пример программы в которой используется класс с двумя конструкторами. Программа предназначена для суммирования чисел, которые могут быть как действительными, так и комплексными.
//Программа для суммирования чисел
#include <iostream>
using namespace std;
class Summa {
public:
Summa(double x,double y); /*Конструктор для суммирования
* действительных чисел x,y */
Summa(double x,double y,double u,double v); /*Конструктор
* суммирования комплексных чисел x+iy, u+iv */
double Re, Im;
}; //Конец класса
//Определение первого конструктора
Summa::Summa(double x,double y){ //Оператор :: называется
Re=x+y; //оператором разрешения области
Im=0; //видимости
}
//Определение второго конструктора
Summa::Summa(double x,double y,double u,double v){
Re=x+u;
Im=y+v;
}
//====================================================
void main(){
bool rule=true; /*Вспомогательная переменная которая определяет
* правило прерывания бесконечного цикла */
double x,y,u,v,z,w;
char ch;
while(rule){
//Выясняем тип чисел для сложения
cout<<"\n\n What numbers do yuor want take summa";
cout<<"Real or Complex\n";
cout<<"If Real inpur R or r if complex then C or c\n";
cin >>ch;
if ((ch=='R') || (ch=='r')){ /*выполняется если числа
* действительные */
cin>>x>>y;
Summa sumRe(x,y); //Создание объекта с именем sumRe
cout<<sumRe.Re;
}
if ((ch=='C') || (ch=='c')){ //выполняется если числа комплексные
cin>>x>>y>>u>>v;
Summa sumCompl(x,y,u,v);
cout<<sumCompl.Re<<" + i"<<sumCompl.Im;
}
if((ch='R')||(ch='r')||(ch='C')||(ch='c')) rule=true;
else rule=false;
}
}
В данном примере конструкторы не просто инициализируют объекты, но и выполняют арифметические действия. Это говорит о том, что конструктор можно использовать для выполнения более сложных задач, чем просто инициализация. При необходимости, в конструкторе можно описать всю программу. Нужно сказать, что конструктор, впрочем, как и функция, может не содержать параметров или иметь параметры по умолчанию. Наконец, в отличие от обычных функций класса, которые в теле класса представлены только в виде прототипов, тело конструктора можно описывать внутри класса.
Рассмотрим пример класса, в котором используется многое из того, о чем было сказано.
class Numbers{
public:
Numbers(int a=1,int b=2, int c=3){//значение по умолчанию
// описание конструктора внутри класса
/* конструктор может использовать имена параметров совпадающие с
* именами полей класса*/
Numbers::a=a;
Numbers::b=b;
Numbers::c=c;
}
show(); //функция класса
private:
int a,b,c; //параметры класса
};
//--------------функия main()----------------
void main(){
Numbers one(1,1,1);
Numbers two(20,30,40);
Numbers defaults;
one.show();
two.show();
defaults.show();
char z;
cin>>z;
}
//-----------описание функции класса-----------
Numbers::show(){
cout<<a<<" "<<b<<" "<<c<<endl;
}
В данном примере объекты oneиtwoопределяются своими наборами чисел, а объектdefaultsинициализируется числами по умолчанию. Конструктор с параметрами по умолчанию гарантирует инициализацию объекта тогда, когда программист забудет это сделать.
В результате на экране появится:
Как правило, в процессе работы программы отпадает надобность в использовании части созданных ранее объектов. Такие объекты просто занимают память. И хотя память современных компьютеров достаточно большая, порой накопление ненужных объектов приводит к её переполнению. Поэтому программист должен следить за тем, чтобы ненужные в дальнейшем объекты своевременно удалялись. Для разрушения существующих объектов в С++ используется специальные функции-члены классов, которые называются деструкторы. Подобно конструктору, деструктор имеет имя класса, впереди которого ставится знак тильда ~. Тип возвращаемого значения не указывается. Синтаксис деструктора следующий:
~имя_класса(){ //тильда и имя без пробелов
//операторы тела деструктора
};
Деструктор это тоже функция, которая не имеет параметров, но может иметь тело. Правда, в теле можно записать совсем немного. Ведь деструктор, после завершения своей работы все равно все уничтожит. Например, можно вывести на экран сообщение о завершении работы класса.
Как всегда, рассмотрим пример:
#include<iostream.h>
#include<windows.h>
//-------------------------------
class Book{
public:
char title[256];
char author[64];
float price;
Book(char *title, char *author,char *publisher, float price);
~Book();
void show_title();
float get_price();
void show_book();
void assign_publisher(char *name);
private:
char publisher[256];
void show_publisher();
};
//--------------------------------
void main(){
SetConsoleOutputCP(1251);
Book primer("C/C++ Примеры и задачи","", "Новое знание",305.0);
primer.show_book();
primer.~Book();
Book classic("Война и мир","Толстой Л.Н.", "Художественная литература", 1000.0);
classic.show_book();
char z;
cin>>z;
}
//----------------------------------
Book::Book(char *title, char *author, char *publisher, float price){
strcpy(Book::title, title);
strcpy(Book::author, author);
strcpy(Book::publisher, publisher);
Book::price=price;
}
//----------------------------------
Book::~Book(){
cout<<"Экземпляр класса закончил работу\n";
}
//---------------------------------
void Book::show_title(){
cout<<author<<" "<<title<<" "<<price<<endl;}
float Book::get_price(){
return price;
}
//----------------------------------
void Book::show_book(){
show_title();
show_publisher();
}
//-----------------------------------
void Book::assign_publisher(char *name){
strcpy(publisher, name);
}
//-------------------------------------
void Book::show_publisher(){
cout<<publisher<<endl;
}
Область видимости класса
Область видимости классов C++, как в случае обычных типов и переменных, распространяется от места их определения до конца блока, в котором это определение дается. Для расширения области видимости класса его можно определить вне всех программных блоков. Кроме того, если класс определен как внешний (extern), то он доступен для всей программы в целом.
Если класс определен как static, то его область видимости такая же, как и для переменной класса памяти automatic, но ее содержимое при этом сохраняется на протяжении всей программы.
В следующем примере в классе Y функция-член func():
- используя : :с-, ссылается на глобальную переменную с;
- используя X: :c, ссылается на переменную внешнего класса;
- используя c ссылается на переменную X: :Y: :c вложенного класса.
Все тpu переменные с именем с доступны при использовании оператора расширения области
видимости
char c; /*Внешняя область видимости*/
class X{/* Объявление класса X */
public:
char c; /* X::c */
class Y{/* Объявление вложенного класса Y */
public:
void func(char e){ X t; :: c=t.X::c=c=e;}
private:
char c; /* X::Y::c */
};
};