рефераты конспекты курсовые дипломные лекции шпоры

Реферат Курсовая Конспект

Основные понятия языка C++. Переменные, константы

Основные понятия языка C++. Переменные, константы - раздел Программирование, Содержание   Лекция № 1. Основные Понятия Языка C++. П...

Содержание

 

Лекция № 1. Основные понятия языка C++. Переменные, константы. Резервирование памяти, инициализация, типы и их значения, символы. Выражения. Операторы. операции. Линейные программы. Операторы отношений. логические операторы. оператор ветвления. 3

Процесс создания программы. 3

Переменные и константы. 4

Оператор ветвления if. 5

Лекция № 2. Циклы. Счётчики. Указатели. память. размещение объектов в области динамической памяти. ссылки. Адреса. передача аргументов функции как ссылок. возвращение нескольких значений. 7

Циклы. 7

Оператор switch. 8

Указатели. 9

Лекция № 3. Функции. Объявление и определение функции. выполнение функции. Локальные и глобальные переменные. Аргументы функции — фактические и формальные. Перегрузка функций. возвращаемые значения. Массивы. 11

Функции. 11

Использование функций. 11

Макрофункции.. 12

Перегрузка функций. 13

Возврат более одного результата. 13

Лекция № 4. Массивы. Элементы массива. инициализация массива. объявление массива. Динамические и статические массивы. Многомерные массивы. Строковые. 15

Массивы. 15

Лекция № 5. Структуры. Доступ к элементам структуры. Инициализация. Выделение памяти. работа с динамическими типами данных . работа со стеком, очередью, деком, деревом. (Самостоятельное изучение) 17

Создание новых типов. 17

Шаблон структуры.. 17

Структурные переменные. 17

Инициализация структуры.. 18

Массив структур. 19

Передача структуры в функцию.. 20

Вложенные структуры.. 20

Лекция № 6. Базовые классы. Классы и члены. Получение доступа к членам класса. Ограничение доступа к членам класса. определение методов класса. Конструкторы и деструкторы. Вложенные классы. структуры. 22

Классы. 22

Доступ к членам класса. 22

Лекция № 7. Перегрузка функций-членов. Инициализация объектов. Перегрузка операторов. Операторы преобразований. Наследование. 24

Дополнительные возможности использования функций. 24

Функции — друзья. 25

Перегрузка операторов. 25

Конструктор-копировщик. 26

Лекция № 8. Наследование Закрытый. Защищённый Форматированный ввод. Ввод-вывод в файл. 28

Наследование. 28

Инициализация наследуемых классов. 28

Потоки. 29

Управление выводом данных: 30

Лекция № 9. Использование файлов для ввода-вывола. 31

Использование файлов для ввода- вывода информации. 31

Строки. 32

Лекция № 10. . Виртуальные методы. Полиморфизм. 33

Виртуальные методы. 33

Как работают виртуальные функции. 33

Абстрактные классы. 35

Лекция № 11. Специальные классы и функции. Вложение. Делегирование. Классы друзья. Функции -друзья. Связные списки. 36

Статические переменные-члены. 36


. История развития языков Концепции структурного и объектно-ориентированного программирования. особенности написания программ для системы Windows, концептуальные отличия .Составные части программы на С++. Использование функций


Лекция № 1.Основные понятия языка C++. Переменные, константы. Резервирование памяти, инициализация, типы и их значения, символы. Выражения. Операторы. операции. Линейные программы. Операторы отношений. логические операторы. оператор ветвления.

Процесс создания программы.

1. Написать исходный файл с расширением .cpp. 2. скомпоновать исходный файл и получить объектный файл с расширением .obj. … 3. скомпоновать предыдущий файл. С необходимыми библиотеками и получить исполняемый файл .exe.

Int main()

{

cout <<”Привет Мир! Меня зовут …n”;

Return 0

}

1. Рассмотрите следующую программу и попытайтесь понять, что она делает, не запуская её на выполнение.

#include <iostream.h>

Int main()

{ int x=5;

int y=7;

cout <<”n”

cout << x+y <<” ”<<x*y;

cout <<”n”

Return 0

}

2 какие ошибки будут при компиляции, почему?

#include <iostream.h>

Int main()

{

cout <<”Привет Мир! Меня зовут …n”

Return 0

  В стороке 1 подключается файл .. в текущий. Сигнал # служит для препроцессора.… Основной код программы начинается в строке 3. при вызове основной функции. Функция — это блок программы, который…

Переменные и константы.

Существует функции sizeof(тип ) При объявлении переменной для неё выделяется память. резервирование памяти не… Рекомендации:

Оператор ветвления if.

Логические операторы.

Схема if( (x==5)

If (условие) выражение;

If(условие)

{

Выражение 1;

Выражение 2;

}

Else

{

Выражение 3;

Выражение 4;

Логические операторы. Оператор Символ А С Результат И && T T F F … Возможна запись: (выражение 1)?(выражение 2): (выражение 3); Пример

Int main(void)

{

Int fistNumb,secondNumb;

cin >>fistNumb; cout <<"nВторое:"; cin >>secondNumb;

Else

cout<<"Число "<<fistNumb<<" делится без остатка на "<<secondNumb<<"n";

}

Else

cout<<"Число "<<fistNumb<<" не делится без остатка на "<<secondNumb<<"n";

}

Else

cout<<"Число "<<fistNumb<<" меньше чем "<<secondNumb<<"n";

Return 0;

}


 

Лекция № 2.Циклы. Счётчики. Указатели. память. размещение объектов в области динамической памяти. ссылки. Адреса. передача аргументов функции как ссылок. возвращение нескольких значений.

Циклы.

Цикл — это блок программы , который необходимо повторить несколько раз. Исторически первые циклы организовывались при помощи оператора безусловного перехода goto;

#include <iostream.h>

Int main(void)

{

int i=0;

loop: i++;

cout << "счётчик ="<<i<<"n";

if(i<5)

Goto loop;

cout <<"конец работыn";

Return 0;

}

Использование оператора goto позволяет написать так называемую “спагетти” плохо читаемую и организованную программу. Поэтому последние 20 лет преподаватели убеждают студентов не использовать этот оператор.

Следующим появился оператор while .в нём выполнение последовательность операторов повторяется пока условие в скобках истино.

#include <iostream.h>

Int main(void)

{

int i=0;

while(i<5)

{

cout <<"счётчик = "<<i<<"n";

I++;

}

cout <<"конец работыn";

Return 0;

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

Int main(void)

{

for (int i=0;i<10;i++)

cout <<"счётчик = "<<i<<"n";

cout <<"конец работыn";

Return 0;

}

Цикл for работает в такой последовательности:

1. Присваивается начальное значение счётчику ( и другие начальные значения);

2. Вычисляется значение выражения на условия продолжения цикла;

3. Если условие возвращает true, то сначала выполняется тело цикла, а затем заданная операция с счётчиком.

4. шаги 2 и 3 повторяются на каждой итерации цикла.

#include <iostream.h>

Int main(void)

{int I,j;

for ( i=0,j=0;i<3;i++,j++)

cout <<"i= "<<i<<" j="<<j<<"n";

I=j=10;

cout <<”I=”<<I<<” j=”<<j<<”n”;

cout <<"конец работыn";

Return 0;

}

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

Оператор switch.

Оператор множественного ветвления.

#include <iostream.h>

 

Int main(void)

{ int number;

cout <<"ВВедите число между 1 и 5: ";

cin >> number;

cout <<"n";

Switch(number)

case 0: cout<<" Очень мало извините!n";break; case 2: cout<<"Уже лучше.n"; case 3: cout<<"Просто хорошо.n";

Return 0;

}

Указатели.

Так как указатель это обычная переменная, то имена им даются такие же, иногда программисты добавляют к ним букву «р». (pNumber). Что бы объявить указатель, запишите тип переменной на которую будет указывать… Что бы присвоить указателю адрес переменной необходимо использовать символ &.

Int I;

Int &ri=I; —это ссылка наI,ссылка обязательно должна быть инициализирована, то есть иметь значение, то есть куда-то ссылаться, однажды инициализировав ссылку ей нельзя присвоить другое значение. Нельзя ri=j; так как ri— это синоним i.

Ссылку можно рассматривать как постоянный указатель, который всегда разадресован, то есть его не надо разадресовывать, для того чтобы получить значения по адресу.

 

Для выделения памяти в области динамического распределения используется оператор new . Для этого подходит строка (тип данных — int) :

Int *page = new int;

Когда память, выделенная под динамическую переменную больше не нужна, то её следует освободить оператором delete имя переменной. При этом переменная указатель сохраняется, но она больше не указывает ни на какой сегмент памяти. Двойное применение delete к одному и тому же указателю приводит к зависанию программы. Поэтому рекомендуется после оператора delete , удалённому указателю присваивать значение 0. С указателями можно производить арифметические действия.

Int *a, b, *c;

*a=b;

c=a++;

с будет указывать на область памяти, следующую за ана 2 байта, так как тип переменной указателя занимает 2 байта.


Лекция № 3.Функции. Объявление и определение функции. выполнение функции. Локальные и глобальные переменные. Аргументы функции — фактические и формальные. Перегрузка функций. возвращаемые значения. Массивы.

Функции.

Использование функций.

Каждая функция обладает собственным именем, и если это имя встречается в программе, то управление переходит к телу этой функции. Этот процесс… Различают два вида функций : встроенные и определённые пользователем. Встроенные функции являются составной частью…

Int MyFunction(int some Value, float SameFloat);

Rezult=MyFunction(12.4,4.7); Использование функций требует что бы функция была сначала объявлена, а потом… Существуют три способы объявления функции:

Int Add(int x, int y);

Int Add(int x,int y)

{

cout << “В Add складываются “ <<x<< “и”<<y<<”n”;

return (x+y);

}

Int main()

{ int a,b,c;

cout <<”Введите два числа:n”;

cin >>a;

cin >> b;

c=Add(a,b);

cout <<”a+b=”<<c<<”n”;

Return 0;

}


Макрофункции

Однако, следует быть очень внимательным с использованием аргументов, поскольку происходит всего лишь подстановка аргумента в строку замещения, после… Пример 3. /* текст программы до обработки препроцессором */

Void main(void)

{

int y=5,rez;

printf("квадрат y равен %dn",SQUARE(y)); printf("квадрат y+2 равен %dn",SQUARE(y+2)); printf("частное равно %fn",100./SQUARE(y));

}

Перегрузка функций.

При вызове функции компилятор создаёт копию функции в памяти, выделяя под неё память, можно выиграть несколько в быстродействии, если использовать…

Inline int Area(int,int);

Возмоожны рекурсивные функции, то есть функции, вызывающие самое себя.

Пример.


#include <iostream.h>

Int fib(int n);

Int fib(int n)

{ if (n<3)

Return 1;

Else

return (fib(n-2)+fib(n-1));

}

Int main(void)

{

Int i,rez;

cout <<"введите число Фибоначи = ";

cin >> i;

rez=fib(i);

cout <<i<<"-oe число Фибоначи ="<<rez<<"n";

Return 0;

}

Результат

введите число Фибоначи = 6

6-oe число Фибоначи =8


Возврат более одного результата.

Пример. #include<iostream.h> #include<conio.h>

Int main(void)

{

Float a,b,c,x1,x2;

Int rez;

cout <<"Введите числаn a:";

cin >>a;

cout <<"n b=:";

cin >>b;

cout <<"n c=:";

cin >>c;

// вызов функции с фактическими параметрами

rez=sqwere(a,b,c,&x1,&x2);

Switch(rez)

{ case 0: cout << "корней нет n";break;

case 1: cout << "корнь один = "<< x1 <<" n";break;

case 2: cout << "корней два x1= "<< x1 <<" x2= "<<x2<<"n";break;

}

Return 0;

Та же самая программа написана при помощи ссылок, найдите отличия #include<iostream.h> #include<conio.h>

Int main(void)

{

Float a,b,c,x1,x2;

Int rez;

cout <<"Введите числаn a:";

cin >>a;

cout <<"n b=:";

cin >>b;

cout <<"n c=:";

cin >>c;

rez=sqwere(a,b,c,x1,x2);

Switch(rez)

{ case 0: cout << "корней нет n";break;

case 1: cout << "корнь один = "<< x1 <<" n";break;

case 2: cout << "корней два x1= "<< x1 <<" x2= "<<x2<<"n";break;

}

Return 0;

}



Лекция № 4.Массивы. Элементы массива. инициализация массива. объявление массива. Динамические и статические массивы. Многомерные массивы. Строковые.

Массивы.

Описание массива: Доступ к элементам массива осуществляется по адресации, относительно первого элемента, то есть, если необходимо…

Randomize();

for(i=0;i<n;i++)

{ for(j=0;j<m;j++)

*(Arrey+i*m+j)=random(zz);

}

Return 0;

}

int exitArrey(int n,int m, int *Arrey)

{ int i;

for(i=0;i<n*m;i++)

(((i+1)%m)==0)? cout<<*(Arrey+i)<<"n" : cout<<*(Arrey+i)<<"t";

Return 0;

}

int* sunArrey(int n,int m,int *Arrey1,int*Arrey2)

{

int*Arrey;

Int i,j;

Arrey=(int*)malloc(sizeof(int)*n*m);

for(i=0;i<n;i++)

for(j=0;j<m;j++)

*(Arrey+i*m+j)=*(Arrey1+i*m+j)+(*(Arrey2+i*m+j));

Return Arrey;

}

Int main(void)

int *ArreyF,*ArreyS,*ArreyRez,n,m,size=100; cout <<"Введите размерность массиваn по строкам:"; cin >>n;

VvodArrey(n,m,ArreyF,size);

vvodArrey(n,m,ArreyS,size/2.);

ArreyRez=sunArrey(n,m,ArreyF,ArreyS);

cout <<"******--1--********n";

ExitArrey(n,m,ArreyF);

cout <<"******--2--*********n";

ExitArrey(n,m,ArreyS);

cout <<"******--3--*********n";

ExitArrey(n,m,ArreyRez);

Return 0;

}

Результат работы программы.


Введите размерность массива

по строкам: 2

по столбцам : 3

******--1--********

64 47 73

8 85 53

******--2--*********

32 23 36

4 42 26

******--3--*********

96 70 109

12 127 79

Введите размерность массива

по строкам: 1

по столбцам : 5

******--1--********

70 44 39 57 46

******--2--*********

35 22 19 28 23

******--3--*********

105 66 58 85 69


***Домашнее задание: переписать программу со статическим выделением памяти.


Лекция № 5.Структуры. Доступ к элементам структуры. Инициализация. Выделение памяти. работа с динамическими типами данных . работа со стеком, очередью, деком, деревом. (Самостоятельное изучение)

Создание новых типов

Тип данных является категорией. В языке С++ программист может создать любой тип данных на основе базовых типов. Новые типы данных необходимо… Успех программы часто зависит от удачного выбора способа представления данных.… Для использования структуры необходимо:

Шаблон структуры

Шаблон - это схема, описывающая содержание структуры. Установка структурного шаблона телефонный справочник:

struct sprav {

char fio[20];

Long num;

Данный шаблон описывает структуру с именем типа структуры sprav, состоящую из двух компонентов: строки fio и целой переменной num типа long. Имя…

Структурные переменные

Объявление структурных переменных приводит к выделению памяти для компонент структуры, куда можно записать данные или откуда можно прочитать их. Для объявления структурных переменных имеются несколько способов.

1. Установить структурный шаблон:

struct sprav {

char fio[20];

Long num;

};

Объявить простую переменную, массив структур, указатель на структуру: struct sprav tel1, tel2[5], *tel3;

2. Установить структурный шаблон с помощью макроопределения:

#define SPRAV struct sprav

SPRAV {

char fio[20];

Long num;

};

Объявить переменные:

SPRAV sp1, sp2[6], *sp3;

3. Объявить переменные одновременно с установкой шаблона (если на данную структуру вы больше не ссылаетесь):

struct {

char fio[20];

Long num;

} tel1, tel2[3], *tel3;

4. Ввести новый тип данных (TEL)-структура определенного вида:

typedef struct {

char fio[20];

Long num;

} TEL;

Объявить переменные нового типа:

TEL tel1, tel2[6], *tel3;

Если программа достаточно объемна, представляется более удобным четвертый способ.

Инициализация структуры

 

Инициализировать можно только внешние или статические структуры.


static struct {

char fio[20];

Long num;

} tel[2]={

"Иванов Ф.А.", 456756,

"Петров В.П.", 632345

};

Доступ к компонентам структуры

Доступ к компонентам структуры продемонстрируем с помощью примеров.

Пример 1.


/* Обращение к элементам структуры через имя переменной */

#include <stdio.h>

#include <conio.h>

Void main(void)

{

struct{

char fio[20]; /* фамилия */

long num; /* телефон */

} tel1, tel2;

Clrscr();

puts("введите фио абонента-");

Gets(tel1.fio);

scanf("%ld",&tel1.num); tel2=tel1; /* нельзя так же сравнивать структуры */ puts("Введено:");

Long num;

};

Void main(void)

{

struct sprav *tel1, *tel2;

Clrscr();

tel1=(struct sprav *)malloc(sizeof(struct sprav)); tel2=(struct sprav *)malloc(sizeof(struct sprav)); puts("введите фио абонента-");

Массив структур

 


Пример 3.

/* Массив структур. Обращение к элементам структуры через */

/* имя элемента массива */

#include <stdio.h>

#include <conio.h>

#include <string.h>

#define SPRAV struct sprav

Void main(void)

{

SPRAV{

char fio[20];

Long num;

};

SPRAV tel[5]; /* массив структур - 5 элементов */

char fio_tek[20];

Int i;

Clrscr();

/* ввод данных в массив структур */

for(i=0; i<5; i++)

{

puts("введите фио абонента-");

gets(tel[i].fio);

puts("введите его номер-");

scanf("%ld",&tel[i].num);

Getchar();

}

puts("Выбор телефона по фамилии");

Gets(fio_tek);

for(i=0; i<5; i++) if(!strcmp(fio_tek,tel[i].fio)) break; if(i!=5) /* цикл закончен по break */

Long num;

} TEL;

Void main(void)

{

TEL *tel;

char fio_tek[20];

Int i;

Clrscr();

/* Выделение памяти для массива - 3 элемента */

tel=(TEL *)malloc(sizeof(TEL)*3);

for(i=0; i<3; i++)

{

puts("введите фио абонента-");

gets((tel+i)->fio);

puts("введите его номер-");

scanf("%ld",&(tel+i)->num);

Getchar();

}

puts("Выбор телефона по фамилии");

Gets(fio_tek);

for(i=0; i<5; i++,tel++)

if(!strcmp(fio_tek,tel->fio)) break;

if(i!=5)

printf("номер абонента %s равен %ldn",fio_tek,

tel->num);

Else

puts("Абонент не найден");

}


Передача структуры в функцию

  Пример 5. /* Передача структуры в функцию через указатель на структуру */

Void main(void)

{

COMPLEX x,y,z;

vvod(&y,6.89,8.45); puts("Введены числа:"); out(&x);

Return;

}

/* Вычисление суммы двух комплексных чисел */

void sum(COMPLEX *p1,COMPLEX *p2,COMPLEX *p3)

{

(*p3).a=(*p1).a+(*p2).a;

(*p3).b=(*p1).b+(*p2).b;

Return;

}

/* Ввод значений для элементов структуры */

void vvod(COMPLEX *p,float a, float b)

{

p->a=a;

p->b=b;

Return;

}

 


Вложенные структуры

Структура, являющаяся компонентом другой структуры, называется вложенной.

Пример 6.

/* Даны четыре точки - центры четырех окружностей. Заполнить структуру окружность, если все окружности проходят через начало координат. */


#include<conio.h>

#include<stdio.h>

#include<math.h>

#include<stdlib.h>

struct POINT {

Float x;

Float y;

};

struct CIRCLE {

struct POINT point; /* вложенная структура */

Double r;

} circle[2], *p;

Void main (void)

{

Int i,j;

Float a,b,c,d;

Clrscr();

Gotoxy(17,1);

cputs("ВВЕДИТЕ КООРДИНАТЫ ТОЧЕК :rn");

for(i=0;i<2;i++)

{

cprintf ("nn ВВЕДИТЕ X: ");

cprintf ("X[%d]= ",i+1);

cscanf("%f",&circle[i].point.x);

cprintf ("n ВВЕДИТЕ Y: ");

cprintf ("Y[%d]= ",i+1);

cscanf ("%f",&circle[i].point.y);

}

P=circle;

Gotoxy(17,12);

cputs("РЕЗУЛЬТАТ:rnn");

for(i=0;i<2;i++)

{

a=p->point.x;

b=p->point.y;

c=sqrt(a*a+b*b);

p->r=c;

cprintf("nРАДИУС : %lf ЦЕНТР (%f,%f)rn",p->r,a,b);

P++;

}


 


Лекция № 6.Базовые классы. Классы и члены. Получение доступа к членам класса. Ограничение доступа к членам класса. определение методов класса. Конструкторы и деструкторы. Вложенные классы. структуры.

Классы.

Новый тип создаётся путём объявления классов. Класс — это просто коллекция переменных, скомбинированная с набором связанных функций. Это совмещение данных и операций над ними в один объект называется инкапсуляция. Данные в классе называют переменными-членами или данными-членами. Функции класса часто выполняют операции над переменными-членами класса и называются функциями-членами или методами класса. Функции члены принадлежат классу так же, как и данные-члены, и определяют функциональные возможности класса.

Для объявления класса используется ключевое слово class. Пример:


Class Cat

{

Unsigned int Age;

Unsigned int Weight;

Void Meow();

};


Объявление класса не резервирует память под данные, здесь только сообщается: о существование класса с таким именем и сколько памяти требуется для каждого объекта этого класса (память выделяется под данные-члены, под методы память не выделяется.

Определение объектов происходит так:

Cat Vaska;

Доступ к членам класса.

Существует оператор прямого доступа (.)

Vaska.Weight =5;

Vaska.Meow();

1. используйте ключевое слово classдля объявления класса. 2. используйте оператор прямого доступа к членам класса и его методам. 3. не путайте объявление с определением.

Class Cat

{

Unsigned int Age;

Unsigned int Weight;

Void Meow();

};

а затем в main()

Cat Vaska;

Vaska.Age=5;


Вызовет ошибку компиляции, так как все члены класса Сat закрыты, а присвоение идёт во внешней к классу функции.

Поэтому необходимо сделать:


Class Cat

{public:

Unsigned int Age;

Unsigned int Weight;

Void Meow();

Согласно общей стратегии объектно-ориентированного программирования данные-члены класса должны быть закрытыми. Доступ следует открыть только к… Это позволяет скрыть от пользователя вид в котором хранятся данные, и если в… #include<iostream.h>

Class Mass

{

int *Arrey;

Int n;

public:

Int getSize();

Void putSize(int ss);

Void getArrey(int ras);

Int putArrey();

Void del();

};

void Mass::getArrey(int ras)

{ int i;

Randomize();

Arrey = new int[n];

for(i=0;i<n;i++)

(Arrey+i)=random(2*ras)-ras;

}

int Mass::putArrey()

{ int i;

for(i=0;i<n;i++)

cout<<*(Arrey+i)<<"t";

cout <<"n";

Return 0;

}

int Mass::getSize()

{ return n;

}

void Mass::putSize(int ss)

{n=ss;

}

void Mass::del()

{delete[] Arrey;

}

Int main(void)

{

int ss,m,size=100;

Mass Arrey;

cout <<"Введите размерность массиваn по строкам:";

cin >>ss;

Arrey.putSize(ss);

cout << "размерность массива = "<<Arrey.getSize()<<"n";

Arrey.getArrey(100);

Arrey.putArrey();

Arrey.del();

Arrey.putArrey();

Return 0;

Любую переменную можно инициализировать, то есть присвоить ей значения, для инициализации объектов класса существуют специальные функции —… Домашняя работа написать предложенную программу, так что бы в ней были…  

Дополнительные возможности использования функций.

Дополнительные возможности позволяют:

§ Перегружать функции-члены:

§ Перегружать операторы.

§ Создавать функции для поддержания классов с динамическим выделением памяти для переменных.

Мы уже говорили о перегрузке функций на занятии посвящённом функциям.Функции-члены можно перегрузить точно так же.


#include<iostream.h>

Class Rect

{ public:

Rect(int width,int height);

~Rect() {}

Void DrawRect(int aWidth,int aHeight);

Void DrawRect();

private:

Int itsWedth;

Int itsHeight;

};

Rect::Rect(int wedth,int height)

{

itsWedth=wedth;

itsHeight=height;

}

void Rect::DrawRect()

{

DrawRect(itsWedth,itsHeight);

}

void Rect::DrawRect(int aWedth,int aHeight)

{

for(int i=0;i<aHeight;i++)

{

for(int j=0; j<aWedth;j++)

cout<<"*";

cout << "n";

}

}

Int main(void)

{

Rect theRect(30,5);

cout <<"Печать того, что уже естьn";

TheRect.DrawRect();

cout <<"Печать новогоn";

TheRect.DrawRect(40,10);

Return 0;

}


Таким же образом можно перегружать конструкторы.

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

Rect::Rect(int wedth,int height):

ItsWedth(wedth),

Особенностью функции, которая имеет параметр по умолчанию является возможность ситуации: если параметр не указывается в скобках при вызове, то он… Выбор между перегруженными функциями и значениями по умолчанию с одной стороны… § Не существует стандартных общепринятых значений, которые можно было бы использовать по умолчанию;

Функции — друзья.

Дружественная функция при вызове не получает указателя *this Объекты классов должны передаваться явно через аппарат параметров. При её вызове нельзя…

Class Y

{

void f1(X&);

void f2(X*);

};

Class X

{

Friend Y;

Int I;

Void f3();

}


Перегрузка операторов.

Форма для перегрузки операторов:

Объявление перегруженных операторов осуществляется так же, как и функций. Используется специальное слово: operator , за которым следует сам перегружаемый оператор. В функциях с одним операндом параметры не задаются

Const класс & класс::operator …();

Перегрузка оператора с двумя операндами требует наличия параметров (константные ссылки на объекты этих классов):

Класс класс::operator + (const класс &rhs) — заголовок и след. Описание

Класс operator + (const класс &)

Рекомендации:

§ перегружайте операторы. Если код программы после этого станет чётче и понятнее.

§ Возвращайте объекты класса из перегруженных операторов.

§ Не увлекайтесь созданием перегруженных операторов, выполняющих несвойственные им функции.

 

#include<iostream.h>

Class V_3d

{

Double x,y,z;

V_3d(const V_3d &v1); // конструктор -копировщик V_3d(double x1=0,double y1=0,double z1=0): // конструктор со значениями по умолчанию

V_3d c;

c.x=x+t.x; c.y=y+t.y; c.z=z+t.z;

Return c;

V_3d V_3d:: operator =(V_3d t) { x=t.x; y=t.y; z=t.z;

Return stream;

}

istream &operator >>(istream &stream,V_3d &t)

{

stream >>t.x>>t.y>>t.z;

Return stream;

}

double V_3d:: mod()

{

return x*x+y*y+z*z;

}

Void main(void)

{

V_3d a;

V_3d b(4,7,10);

V_3d c(b);

cout << "координаты вектора b: n";

cout <<b;

cout << "координаты вектора c: n";

C.print();

cout <<"введите координаты вектора a:n";

cin >>a;

cout << "координаты вектора а: n";

cout <<a;

c=a+b;

cout << "координаты вектора a+b n";

C.print();

}

Результат работы программы:

координаты вектора b:

x=4,y=7,z=10

координаты вектора c:

x=4 y=7 z=10

введите координаты вектора a:

-1 3 6

координаты вектора а:

x=-1,y=3,z=6

координаты вектора a+b

x=3 y=10 z=16


Конструктор-копировщик.

Вторая схема представляет поверхностное копирование (если один из компонентов класса содержит указатель) и в случае уничтожения этого данного,… Первая схема для глубинного копирования позволяет полностью скопировать все…  

Наследование.

Наследование является иерархической системой, позволяющей лучше выразить взаимодействия между классами. Иерархия представляет собой вид отношений… Когда мы говорим, что нечто является видом чего-либо, мы подразумеваем большую… В С++ иерархичность реализована в концепции классов — когда один класс может наследовать или происходить от класса…

Class base

{ int x;

public:

void setx(int n){x=n;}

void prinx(){cout<<"x="<<x<<"n";}

};

class deriv : private base

{

Int y;

public:

void setxy(int n,int m){setx(n);y=m;}

void prinxy(){prinx();cout<<"y="<<y<<"n";}

};

Void main(void)

{

Deriv ob;

cout <<"результат работы программы: n" ;

Ob.setxy(10,25);

Ob.prinxy();

}

результат работы программы:

X=10

y=25


Инициализация наследуемых классов.

Все действия по инициализации объектов выполняет конструктор порождённого класса.

Если конструктору базового класса требуются аргументы, то они должны быть указаны в списке аргументов конструктора. В общем виде конструктор имеет вид:

Конструктор_производного_класса(список аргументов): базовый_класс1( список аргументов)…базовый_класс_N (список аргументов) { тело конструктора}

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


#include <iostream.h>

Class B1

{ public:

B1(){cout<<"работа конструктора B1n";}

~B1(){cout<<" работа деструктора B1n";}

};

Class B2

{ public:

B2(){cout<<"работа конструктора B2n";}

~B2(){cout<<" работа деструктора B2n";}

};

class D:public B1,public B2

{

public:

D(){cout<<"работа конструктора Dn";}

~D(){cout<<" работа деструктора Dn";}

};

Void main(void)

{

cout <<"результат работы программы: n" ;

D ob;

cout<<"*********************n" ;

}

результат работы программы:

Работа конструктора B1

Работа конструктора B2

Работа конструктора D

*********************

Работа деструктора D

Работа деструктора B2

Работа деструктора B1


Конструкторы базового класса должны быть объявлены с атрибутами protected или publicдля того, чтобы обеспечить возможность их вызова из класса-наследника.

Потоки.

Операция записи на диск достаточно временноёмка, поэтому используют буфер обмена. В С++ используется ОО подход к реализации обмена данными с буферными… § Класс streambuf управляет буфером, его методы позволяют наполнить, опорожнить и очистить буфер.

Int main(void)

{

Char ch;

while((ch=cin.get())!=EOF)

{

cout << "ch: "<<ch<<endl;

}

cout <<"n конец n";

Return 0;

cin.get() возвращает не объект типа iostream, а тип int. А если вы используете параметр cin.get(a), то возвращается объект iostream, а параметру… § указатель на массив символов. § максимально-возможное количество символов в строке, включая концевой символ;

Int main(void)

{

Char ch;

cout <<"введите фразу: ";

While(cin.get(ch))

{

if(ch=='!') cin.putback('$');

else cout <<ch;

while(cin.peek()=='#')

cin.ignore(1,'n');

}

Return 0;

Результат работы программы: введите фразу: кен!!gh#ghj##sdfdgfh // кен$$ghghjsdfdgfh

Использование файлов для ввода- вывода информации.

Объектами iostream поддерживаются флаги, отражающие состояние ввода-вывода. Значение их можно получить при помощи функций. § Eof() — возвращает TRUE, если в потоке встречается символ EOF (конец… § Bad() — возвращает TRUE при попытке ошибочной операции.

F1.close();

F2.close();

#include<fstream.h>

#include<iostream.h>

Void main(void)

{ char ch;

int num=0;

char buffer[255];

ofstream fout("rez.txt");

cout<<"результат работы программы: n";

cin.ignore(1,'n');

Cin.getline(buffer,255);

fout<<buffer<<"n";

Fout.close();

ifstream fin("rez.txt");

fin.unsetf(ios::skipws);

while(!fin.eof())

{fin>>ch;

cout<<ch;

num++;

}

cout <<"n файл закончилсяn число символов :"<<num<<"n";

Fin.close();

}

результат работы программы:

укнеку нгшгнш №;%435435прорлорл рорлордло олодлод

кнеку нгшгнш №;%435435прорлорл рорлордло олодлод

Файл закончилс

число символов :50


Строки.

Пример: char *Family=”Орешкина”; char Kreek[]=” Helloy, Word!”; #include<iostream.h> #include <alloc.h>

Switch(i)

{

case 0: cout <<"они равныn";break;

case-1: cout <<"1-ое меньшеn";break;

case 1: cout <<"1-ое большеn";break;

}

}

Int main(void)

{

char stroka[80],*ptr,string[80],c='*';

Int i;

cout<<"/*результат работы программыn";

cout <<"Введите строку:";

cin >>stroka;

I=strlen(stroka);

cout <<"_______"<< stroka<<"n"; strcpy(string,stroka); //копирование второй строки в первую cout <<"*******"<< string<<"n";

Srav(string,stroka);

Srav(stroka,stroka);

Srav(stroka,string);

ptr = strchr(stroka, c); //проверка на вхождение символа.

If (ptr)

cout << "Символ "<< c <<" находится на " << ptr-stroka+1 << "позицииn" ;

Else

cout<<"Этого символа нет в строке";

cout<<"*//";

Return 0;

}

Результат работы программы

Введите строку: Привет

длина строки Привет=6

_______Привет

*******Привет

^^^^^^^Привет* Это Я

1-ое: Привет,2-ое:Привет* Это Я

Ое меньше

1-ое: Привет* Это Я,2-ое:Привет* Это Я

Они равны

1-ое: Привет* Это Я,2-ое:Привет

Ое больше

Символ * находится на 7позиции



Лекция № 10.. Виртуальные методы. Полиморфизм.

Виртуальные методы.

Как работают виртуальные функции.

Предположим, что существует класс GrafObj(x,y) — базовый класс, исходный от него класс Cub(d,w). При создании объекта класс Cub, сначала выполниться… на рисунках представлены схемы работы виртуальной функции Draw VPTR —… #include<iostream.h>

Class X

{ public:

Virtual double A(double x)

{ return x*x; }

Double B(double x)

{ cout<<A(x)<<":2=";

return A(x)/2.; }

};

class Y:public X

{ public:

Double A(double x)

{ return x*x*x; }

};

Int main(void)

{

Y y;

X x;

cout<<"при x=3."<<endl;

cout<<x.B(3.)<<" X"<<endl;

cout<<y.B(3.)<<" Y"<<endl;

}

результат выполнения программы:

при x=3.

9:2=4.5 X A::X=x*x;

27:2=13.5 Y A::Y=x*x*x


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


#include<iostream.h>

Class Mammal

{ public:

Mammal():itsAge(1){}

virtual ~Mammal() {}

virtual void Speak() { cout<< " Млекопитающее что-то сказало!n";}

protected:

Int itsAge;

};

class Dog:public Mammal

{ public:

void Speak(){cout<<"Гафф!n";}

};

class Cat:public Mammal

{ public:

void Speak(){cout<<"Мурр!n";}

};

Void VFunc(Mammal);

void PFunc(Mammal*);

void RFunc(Mammal&);

Int main(void)

{

Mammal *prt=0;

Int choice;

While(1)

{

bool fQ=false;

cout<<"1--собака, 2-- кошка, иначе-- млекопитающее, 0-- выход.";

cin>> choice;

Switch(choice)

{

case 0: fQ=true;break;

case 1: prt=new Dog; break;

case 2: prt=new Cat; break;

default: prt=new Mammal;

}

If(fQ) break;

cout<<"указатель на класс: " ; Pfunc(prt);

cout<<"ссылка на класс: "; Rfunc(*prt);

cout<<"переменная класса: -- "; VFunc(*prt);

}

Return 0;

}

Void VFunc(Mammal M)

{ MV.Speak(); }

void PFunc(Mammal *pM)

{ pM->Speak(); }

void RFunc(Mammal &rM)

{ rM.Speak(); }


/* результат работы программы:

Собака, 2-- кошка, иначе-- млекопитающее, 0-- выход. 1

указатель на класс: -- Гафф!

ссылка на класс: -- Гафф!

переменная класса: -- Млекопитающее что-то сказало!

Собака, 2-- кошка, иначе-- млекопитающее, 0-- выход. 2

указатель на класс: -- Мурр!

ссылка на класс: -- Мурр!

переменная класса: -- Млекопитающее что-то сказало!

Собака, 2-- кошка, иначе-- млекопитающее, 0-- выход. 3

указатель на класс: -- Млекопитающее что-то сказало!

ссылка на класс: -- Млекопитающее что-то сказало!

переменная класса: -- Млекопитающее что-то сказало!

Собака, 2-- кошка, иначе-- млекопитающее, 0-- выход. 0

Конструктор не может быть виртуальным и не может быть виртуального конструктра-копировщика. Если требуется передать указатель на объект… Virtual Mammal* Mammal::Clone(){return new Mammal(*this);} Virtual Mammal* Dog::Clone(){return new Dog(*this);}

Абстрактные классы.

Очень часто виртуальная функция, объявленная в базовом классе, никогда не используется в нём, то есть она представляется в виде пустой функции ( { } ).

Версия виртуальной функции, которая должна быть определена, но никогда не будет использоваться, должна быть объявлена как чисто виртуальная :

Virtual тип имя_функции (список параметров) =0;

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

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

Рекомендации:

§ Используйте абстрактные типы данных для создания для создания общего интерфейса для всех производных классов.

§ Обязательно замещайте в произвольных классах чистые виртуальные функции.

§ Объявляйте все функции, которые требуют замещения в произвольном классе как виртуальные.

§ Не пытайтесь создать объект абстрактного класса.


Лекция № 11.Статические переменные. Шаблоны функций и классов. Связные списки.

Статические переменные-члены и статические функции-члены.

#include<iostream.h>

Class Cat

{

public:

Cat(int age):itsAge(age){HayMenyCats++;}

virtual ~Cat(){HayMenyCats--;}

virtual int GetAge() {return itsAge;}

virtual void SetAge(int age){itsAge=age;}

Static int HayMenyCats;

private:

Int itsAge;

};

int Cat::HayMenyCats =0;

Int main(void)

{

const int MaxCat=5;

Int i;

Cat *CatHouse[MaxCat];

for(i=0;i<MaxCat;i++)

CatHouse[i]=new Cat(Maxcat-i);

for(i=0;i<MaxCat;i++)

{

cout<<"сейчас у нас ";

cout<<Cat::HayMenyCats;

cout<<" кота.n";

cout<<"удалим кота, возраст которого ";

cout<<CatHouse[i]->GetAge()<<" года n";

delete CatHouse[i];

CatHouse[i]=0;

}

Return 0;

}

у нас живёт 4 кота .

Удалим кота, возраст которого 4 года

у нас живёт 3 кота .

Удалим кота, возраст которого 3 года

у нас живёт 2 кота .

Удалим кота, возраст которого 2 года

у нас живёт 1 кота .

Удалим кота, возраст которого 1 года

§ Применять статические переменные для совместного использования данных несколькими объектами класса. § Необходимо ограничить доступ к статическим ,объявив их private или… § Не используйте статические данные для хранения данных одного объекта. Эти переменные предназначены для обмены…

Class Cat

{

public:

Cat(int age) :itsAge(age) {HayMenyCats++;}

virtual ~Cat(){HayMenyCats--;}

virtual int GetAge() {return itsAge;}

virtual void SetAge(int age) {itsAge=age;}

Static int GetHayMeny()

{ return HayMenyCats;}

private:

Int itsAge;

Static int HayMenyCats;

};

Void Info();

int Cat::HayMenyCats =0;

Int main(void)

{

const int MaxCat=4;

Int i;

Cat *CatHouse[MaxCat];

for(i=0;i<MaxCat;i++)

{

CatHouse[i]=new Cat(MaxCat-i);

Info();

cout<<CatHouse[i]->GetAge()<<" годаn";

}

for(i=0;i<MaxCat;i++)

{ cout<<"удаляем старшего кота n"<<endl;

delete CatHouse[i];

CatHouse[i]=0;

Info();

}

Return 0;

}

Void Info()

cout<< "у нас живёт "<< Cat::GetHayMeny()<<" кота .n"; } Вызов статических функций может быть двух видов:

Шаблоны функций и классов

Шаблоны представляют ещё одну реализацию полиморфизма в программах С++. Они позволяют создать универсальный фрагмент кода, а затем использовать его многократно с различными типами данных или различными объектами. С помощью шаблонов можно уменьшить объём и сложность программы.

Шаблоны функций позволяют передавать в качестве аргумента тип переменной. Шаблоны создают семейства функций, определяющее неограниченное множество родственных функций. Экземпляризация— операция создания определённого типа из шаблона. Отдельные классы называются экземплярами шаблона. Параметризованные шаблоны — представляют возможность создания общего класса и для построения конкретных экземпляров передают этому классу в качестве параметров типы данных.

На пример список. Список может быть для чего угодно.

Построение шаблонов рассмотрим на примере. Необходимо написать функцию расчёта куба для аргумента. (Cub()).


#include<iostream.h>

#include<math.h>

template <class T>

T cub(T x)

{ return x*x*x;}

template <class SwapType>

void Swap(SwapType &x,SwapType &y)

{ SwapType tmp;

tmp=x;

X=y;

y=tmp;

}

template <class T1,class T2>

T1 max(T1 x,T2 y)

{

if(x>y)return x;

Else return y;

}

Void main(void)

int i=3; float f=3.12; double x=3.1e2;

Шаблоны классов.

Шаблон класса представляет собой скелет обобщённого класса. Ситаксис такой:

Template< список_аргументов_шаблона>

{

//тело класса

};

Каждый аргумент в списке является либо объявлением типа float a; либо идентификатором класса class T. Из-за этого определение функции-метода шаблонного класса имеет вид:

Template< список_аргументов_шаблона>

Тип_результата имя_класса < список_аргументов_шаблона>::

Имя_функции( список_аргументов_функции)

{

//тело функции.

}

объявление объекта шаблонногокласса:

имя_класса_шаблона < список_аргументов_шаблона> имя_объекта;

Пример использования шаблонов будем рассматривать на создании очереди.

Связные списки и другие структуры.

Существуют три основных вида списков: § Однонаправленные списки (очередь, стек); § Двунаправленные списки (дек и т.д.);

Class Data

{

public:

Data ();

~Data(){delete fam;}

int Compare(const Data &);

Void Show();

private:

char fam[25];

Float ball;

};

Data::Data()

{

cout<<"n Введите фамилию и средний балл :";

cin>>fam>>ball;

}

void Data::Show()

{ cout.width(25);

cout.fill(' ');

cout<<fam;

Cout.width(10);

cout.fill('-');

Cout.precision(3);

cout<<ball<<"n";

Fout.width(25);

fout.fill(' ');

fout<<fam;

Fout.width(10);

fout.fill('-');

Fout.precision(3);

fout<<ball<<"n";

//fout<<fam<<"--"<<ball<<endl;

}

int Data::Compare(const Data &theO)

{

if(strcmp(fam,theO.fam)<0)return -1;

if(strcmp(fam,theO.fam)==0)return 0;

if(strcmp(fam,theO.fam)>0)return 1;

}

Class Node;

Class HeadNode;

Class TailNode;

Class InternalNode;

Class Node

Node(){} virtual ~Node(){} virtual Node* Insert(Data* theData)=0;

MyData(theData),myNext(next)

{}

Node* InternalNode ::Insert(Data *theData)

{

int result=myData->Compare(*theData);

Switch(result)

{

case 0:

case1:{InternalNode *dataN=new InternalNode (theData,this);

return dataN;}

case-1:{myNext=myNext>Insert(theData);

return this;}

}

Return this;

}

class TailNode:public Node

{

public:

TailNode(){}

~TailNode() {}

virtual Node* Insert(Data *theData);

virtual void Show(){ }

private:

};

Node* TailNode::Insert(Data *theData)

{

InternalNode *dataN=new InternalNode (theData,this);

Return dataN;

class HeadNode:public Node {public: HeadNode(){myNext=new TailNode;};

Return this;

}

Class Admin

{public:

Admin();

~Admin(){delete myHead;}

void Insert(Data* pData);

void ShowAll(){myHead->Show();}

private:

HeadNode* myHead;

};

Admin::Admin()

{

myHead=new HeadNode;

}

void Admin:: Insert(Data*pData)

{

myHead->Insert(pData);

}

Int main()

{

Data* pData;

int val=1;

Admin ll;

while(val!=0)

{

pData=new Data();

Ll.Insert(pData);

cout<<"хотите закончить ввод? Если да, то введите 0";

cin >>val;

}

Ll.ShowAll();

cout<<"********************************n";

Fout.close();

Return 0;

}


 

 

– Конец работы –

Используемые теги: основные, понятия, языка, Переменные, константы0.077

Если Вам нужно дополнительный материал на эту тему, или Вы не нашли то, что искали, рекомендуем воспользоваться поиском по нашей базе работ: Основные понятия языка C++. Переменные, константы

Что будем делать с полученным материалом:

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

Еще рефераты, курсовые, дипломные работы на эту тему:

Грамматика как языковой уровень. Морфология и смежные уровни языка; морфология и фонология; основные понятия морфонологии; морфология и синтаксис
Термин quot морфология quot состоит из двух древнегреческих корней и буквально означает quot учение о форме quot Он имеет два основных... Система механизмов языка обеспечивающая построение и понимание его... раздел грамматики изучающий закономерности функционирования и развития этой системы...

Грамматика как языковой уровень. Морфология и смежные уровни языка; морфология и фонология; основные понятия морфонологии; морфология и синтаксис
Термин морфология состоит из двух древнегреческих корней и буквально означает учение о форме Он имеет два основных значения... Система механизмов языка обеспечивающая построение и понимание его... раздел грамматики изучающий закономерности функционирования и развития этой системы...

ОСНОВНЫЕ ПОНЯТИЯ И ОПРЕДЕЛЕНИЯ. ЭЛЕМЕНТЫ ЯЗЫКА. ЭЛЕМЕНТЫ ДАННЫХ. ВЫРАЖЕНИЯ. ОСНОВНЫЕ ИНСТРУКЦИИ. ПРОЦЕДУРЫ. ПРЕПРОЦЕССОР. СТИЛЬ ПРОГРАММИРОВАHИЯ
ВВЕДЕНИЕ... ОСНОВНЫЕ ПОНЯТИЯ И...

ОСНОВНЫЕ ПОНЯТИЯ АЛГОРИТМИЧЕСКОГО ЯЗЫКА
Тип констант в языке ПАСКАЛЬ определяется по их виду константы целого типа это целые числа не содержащие десятичной точки константы... ПЕРЕМЕННЫЕ ИНИЦИАЛИЗАЦИЯ... ОПЕРАТОР ПРИСВАИВАНИЯ...

Два объекта истории русского языка: живой язык диалектный и литературный язык
Новые общественные функции приобретает русский язык по мере сложения новой исторической общности советского народа он становится межнациональным... Современный период... Горшкова Хабургаев ИГРЯ...

Понятие литературный язык. Место литературного языка среди других форм существования языка
Литературный язык это язык государственных и культурных учреждений школьного обучения радио и телевидения науки публицистики художественной... Современный литературный язык многофункционален Он используется в различных... Основные сферы использования литературного языка телевидение и кино наука и образование печать и радио...

Понятие о языке и речи. Основные функции языка
Понятие о языке и речи Основные функции языка... Понятие об основных и дополнительных формах существования языка Разнообразие... Литературный язык как высшая форма существования национального языка Основные черты литературного языка...

Основные понятия теории вероятностей. Случайное событие. Вероятность. Статистическая вероятность. Геометрическая вероятность. Основные формулы комбинаторики
Случайные события... Случайные события бывают х видов... Невозможные Обозначение V Достоверные Случайные...

Основные макроэкономические понятия. Список основных макроэкономических элементов. Классическая теория
В литературе можно найти много определений экономической теории Вот одно из них Экономическая теория исследует проблемы эффективного... Объект исследования экономической теории называется экономикой... Понятно что составление модели является очень важной частью исследования Вопрос о том что существенно и...

Основные понятия термодинамики. Предмет термодинамики. Основные параметры состояния термодинамической системы
На сайте allrefs.net читайте: Конспект лекций Дисциплина по учебному плану направления подготовки: 260901 Технология швейных изделий. Омск СОДЕРЖАНИЕ...

0.038
Хотите получать на электронную почту самые свежие новости?
Education Insider Sample
Подпишитесь на Нашу рассылку
Наша политика приватности обеспечивает 100% безопасность и анонимность Ваших E-Mail
Реклама
Соответствующий теме материал
  • Похожее
  • По категориям
  • По работам