Similar presentations:
Объектно-ориентированное программирование. Практическое занятие №1. Введение в язык С++
1. Объектно-ориентированное программирование
Объектноориентированноепрограммирование
Практическое занятие №1.
Введение в язык С++
Автор: И.О. Архипов, к.т.н., доцент
2. 1.1. Отличия С и С++
1. Если в С функция не имеет параметров, ее прототип содержитслово void в списке параметров функции. Например, если в С функция
fl() не имеет параметров (и возвращает char), ее прототип будет выглядеть следующим образом:
char fl(void);
В С++ слово void не обязательно. Поэтому в С++ прототип обычно
пишется так:
char fl ();
2) В программах С++ все функции должны иметь прототипы. В С
прототипы функций рекомендуются, но технически они не обязательны.
Содержащийся в классе прототип функции-члена действует так же, как
ее обычный прототип, и другого прототипа не требуется.
3) Если в С++ функция имеет отличный от void тип возвращаемого
значения, то инструкция return внутри этой функции должна содержать
значение данного типа.
3. 1.1. Отличия С и С++
4) В С, если тип возвращаемого функцией значения явно незадан, функция по умолчанию возвращает значение целого типа. В
С++ такого необходимо явно объявлять тип возвращаемого значения
функции.
5) В программах С++ можно выбирать место для объявления
локальных переменных. В С локальные переменные могут
объявляться только в начале блока, перед любой инструкцией
"действия".
6) Для хранения значений булева типа в С++ определен тип данных bool.
В С++ также определены ключевые слова true и false — единственные
значения, которыми могут быть данные типа bool. В С++ результатом
выполнения операторов отношения и логических операторов являются
значения типа bool. В булевом и в целом выражениях ненулевое значение
автоматически преобразуется в true, а нулевое — в false. Использование
данных булева типа не обязательно, но удобно.
4. 1.1. Отличия С и С++
7) В языке С, при использовании библиотечной функции впрограмму необходимо включить заголовочный файл:
#include <stdio.h>
В Standard С++ вместо имен заголовочных файлов указываются
стандартные идентификаторы:
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <cmath>
#include <cstring>
8) Пространство имен — это некая область, необходимая для
того, чтобы избежать конфликтов имен идентификаторов. Заголовки
нового стиля помещаются в пространстве имен std.
using namespace std;
5. 1.2. Введение в перегрузку функций
// Перегрузка abs() двумя способами#include <iostream>
using namespace std;
long abs(long n);
double abs(double n);
int main(int argc, char* argv[])
{
cout << "Abs -20L:" << abs(-20L) << "\n";
cout << "Abs -10.01:" << abs(-10.01) << "\n";
return 0;
}
6. 1.2. Введение в перегрузку функций
// abs() для длинных целыхlong abs(long n)
{
cout << "Long abs()\n";
return n<0 ? -n: n;
}
// abs() для вещественных двойной точности
double abs(double n)
{
cout << "Double abs()\n";
return n<0 ? -n: n;
}
7. 1.3. Введение в классы
Синтаксис объявления класса:class имя_клаcca {
закрытые функции и переменные класса
public:
открытые функции и переменные класса
} список_объектов;
Пример объявления класса
class myclass {
int а; // закрытый элемент класса
public:
void set_a(int num);
int get_a();
};
8. 1.3. Введение в классы
Основная форма определения функции-члена класса:Тип_возвр_значения имя_класса::имя_функции(параметры)
{
... // тело функции
}
Определение функций-членов set_a() и get_a().
void myclass::set_a(int num)
{
a=num;
}
int myclass::get_a()
{
return а;
}
9. 1.3. Введение в классы
Объявление и использование объектов типа myclassint main()
{
myclass obl, ob2;
obl.set_a(10);
ob2.set_a(99);
cout << obl.get_a() << "\n";
cout << ob2.get_a() << "\n";
return 0;
}
10. 1.3. Введение в классы
// Этот фрагмент содержит ошибку#include <iostream>
using namespace std;
int main() {
myclass obi, ob2;
ob1.a = 10; // ОШИБКА! к закрытому члену нет
ob2.а = 99; // доступа для функции — не члена
cout « ob1.get_a() « "\n";
cout « ob2.get_a() « "\n";
return 0;
}
11. 1.3. Введение в классы. Класс stack.
#include <iostream>using namespace std;
#define SIZE 3
// Объявление класса stack для символов
class stack {
char stck[SIZE];
// содержит стек
int tos;
// индекс вершины стека
public:
void init();
// инициализация стека
void push(char ch); // помещает в стек символ
char pop();
// выталкивает из стека символ
};
// Инициализация стека
void stack::init() {
tos=0;
}
12. 1.3. Введение в классы. Класс stack.
// Помещение символа в стекvoid stack::push(char ch) {
if (tos==SIZE)
{
cout << "Stack is full"
return;
}
stck[tos] = ch;
tos++;
}
<< "\n";
// Выталкивание символа из стека
char stack::pop()
{
if (tos==0)
{
cout << "Stack is empty" << "\n";
return 0; // возврат нуля при пустом стеке
}
tos--;
return stck[tos];
}
13. 1.3. Введение в классы. Класс stack.
int main(int argc, char* argv[]){stack sl, s2;
// создание двух стеков
int i ;
sl.init();
// инициализация стека s1
s2.init();
// инициализация стека s2
sl.push('a');
s2.push('x');
sl.push('b');
s2.push('y');
sl.push('c');
s2.push('z');
sl.push('v'); // попытка записи в переполненный стек
for(i=0;i<3;i++)
cout << "From stack sl:" << sl.pop() << "\n";
for(i=0;i<3;i++)
cout << "From stack s2:" << s2.pop() << "\n";
// попытка чтения из пустого стека
cout << "From stack sl:" << sl.pop() << "\n";
return 0;
}
14. 1.3. Введение в классы. Класс stack.
Результат работы программы15. 1.4. Конструкторы и деструкторы.
#include <iostream>using namespace std;
class myclass {
int а;
public:
myclass(); // конструктор
void show();
};
myclass::myclass () {
cout << "Работа конструктора\n";
a = 10;
}
void myclass::show() {
cout << а;
}
int main() {
myclass ob;
ob.show();
return 0;
}
Пример класса с
конструктором
16. 1.4. Конструкторы и деструкторы.
#include <iostream>using namespace std;
Пример класса с
class myclass {
деструктором
int а;
public:
myclass(); // конструктор
~myclass(); // деструктор
void show();
};
myclass::myclass() {
cout << "Работа конструктора\n";
а = 10;
}
myclass::~myclass() {
int main() {
cout << "Удаление...\n";
myclass ob;
}
b.show();
void myclass::show() {
return 0;
cout << а << "\n";
}
}
17. 1.4. Конструкторы и деструкторы. Класс stack с инициализацией.
#include <iostream>using namespace std;
#define SIZE 3
// Объявление класса stack для символов
class stack {
char stck[SIZE];
// содержит стек
int tos;
// индекс вершины стека
public:
stack();
// конструктор
void push(char ch); // помещает в стек символ
char pop();
// выталкивает из стека символ
};
// Инициализация стека
stack::stack() {
cout << "Работа конструктора стека\n";
tos=0;
}
18. 1.4. Конструкторы и деструкторы. Класс stack с инициализацией.
// Помещение символа в стекvoid stack::push(char ch) {
if (tos==SIZE)
{
cout << "Stack is full" << "\n";
return;
}
stck[tos] = ch;
tos++;
}
// Выталкивание символа из стека
char stack::pop()
{
if (tos==0)
{
cout << "Stack is empty" << "\n";
return 0; // возврат нуля при пустом стеке
}
tos--;
return stck[tos];
}
19. 1.4. Конструкторы и деструкторы. Класс stack с инициализацией.
int main(int argc, char* argv[]){// создание двух автоматически инициализируемых стеков
stack sl, s2;
int i ;
sl.push('a');
s2.push('x');
sl.push('b');
s2.push('y');
sl.push('c');
s2.push('z');
sl.push('v'); // попытка записи в переполненный стек
for(i=0;i<3;i++)
cout << "From stack sl:" << sl.pop() << "\n";
for(i=0;i<3;i++)
cout << "From stack s2:" << s2.pop() << "\n";
// попытка чтения из пустого стека
cout << "From stack sl:" << sl.pop() << "\n";
return 0;
}
20. 1.4. Конструкторы и деструкторы. Класс strtype.
#include <iostream>#include <cstring>
#include <cstdlib>
using namespace std;
#define SIZE 255
class strtype {
char *p;
int len;
public:
strtype();
// конструктор
~strtype(); // деструктор
void set(char *ptr);
void show();
};
21. 1.4. Конструкторы и деструкторы. Класс strtype.
// Инициализация объекта строкаstrtype::strtype()
{
cout << "Constructor\n";
p=new char [SIZE];
if(!p)
{
cout << "Memory error\n";
exit (1);
}
*p='\0';
len=0;
}
22. 1.4. Конструкторы и деструкторы. Класс strtype.
// Освобождение памяти при удалении объекта строкаstrtype::~strtype()
{
cout << "Memory free\n";
if (p) {
delete [] p;
p=NULL;
}
}
23. 1.4. Конструкторы и деструкторы. Класс strtype.
void strtype::set(char *ptr){
if(strlen(ptr) >=SIZE)
{
cout << "Big str\n";
return;
}
strcpy(p, ptr);
len=strlen(p);
}
void strtype::show()
{
cout << p << " - size:
}
" << len << "\n";
24. 1.4. Конструкторы и деструкторы. Класс strtype.
int main(int argc, char* argv[]){
strtype sl,s2;
sl.set("First string");
s2.set("I like C++ !!!");
sl.show();
s2.show();
return 0;
}
25. 1.4. Конструкторы и деструкторы. Класс timer.
#include <iostream>#include <ctime>
using namespace std;
class timer {
clock_t start;
public:
timer();
// конструктор
~timer();
// деструктор
};
timer::timer()
{
start=clock();
}
26. 1.4. Конструкторы и деструкторы. Класс timer.
timer::~timer(){
clock_t end;
end=clock();
cout << "Затраченное время:“;
cout << (end-start)/CLOCKS_PER_SEC <<"\n";
}
int main(int argc, char* argv[])
{
timer ob;
char c;
// Пауза ...
cout << "Нажмите любую клавишу,
cin >> c;
return 0;
}
затем ENTER:
";
27. 1.4.1. Конструкторы с параметрами.
#include <iostream>using namespace std;
class myclass {
int а;
public:
myclass(int x);
void show();
};
int main() {
myclass ob(4);
ob.show();
return 0;
}
myclass::myclass(int x) {
cout << "Работа конструктора\n";
а = x;
}
void myclass::show() {
cout << а << "\n";
}
28. 1.4.1. Конструкторы с параметрами. Класс stack.
#include <iostream>using namespace std;
#define SIZE 3
// Объявление класса stack для символов
class stack {
char stck[SIZE];
// содержит стек
int tos;
// индекс вершины стека
char who;
// идентификатор стека
public:
stack(char c);
// конструктор стека
void push(char ch); // помещает в стек символ
char pop();
// выталкивает из стека символ
};
29. 1.4.1. Конструкторы с параметрами. Класс stack.
// Инициализация стекаstack::stack(char c) {
tos=0;
who=c;
cout << "Constructor of stack " << who << "\n";
}
// Помещение символа в стек
void stack::push(char ch) {
if (tos==SIZE)
{
cout << "Stack " << who << " is full" << "\n";
return;
}
stck[tos] = ch;
tos++;
}
30. 1.4.1. Конструкторы с параметрами. Класс stack.
// Выталкивание символа из стекаchar stack::pop()
{
if (tos==0)
{
cout << "Stack " << who << " is empty" << "\n";
return 0; // возврат нуля при пустом стеке
}
tos--;
return stck[tos];
}
31. 1.4.1. Конструкторы с параметрами. Класс stack.
int main(int argc, char* argv[]){// создание и инициализация двух стеков
stack sl('A'), s2('B');
int i ;
sl.push('a');
s2.push('x');
sl.push('b');
s2.push('y');
sl.push('c');
s2.push('z');
sl.push('v'); // попытка записи в переполненный стек
for(i=0;i<3;i++)
cout << "From stack sl:" << sl.pop() << "\n";
for(i=0;i<3;i++)
cout << "From stack s2:" << s2.pop() << "\n";
// попытка чтения из пустого стека
cout << "From stack sl:" << sl.pop() << "\n";
return 0;
}
32. 1.4.1. Конструкторы с параметрами. Класс stack.
Результат работыкласса stack (версия 1)
Результат работы
класса stack
(версия с именем объекта)
33. 1.5. Введение в наследование.
Наследование — это механизм, посредством которого один класс можетнаследовать свойства другого.
Основная форма наследования:
class производный_класс:спецификатор_доступа базовый_класс
{
...
};
спецификатор_доступа — это одно из следующих трех ключевых слов:
1. public (открытый);
2. private (закрытый);
3. protected (защищенный).
34. 1.5. Введение в наследование.
Простой пример наследования#include <iostream>
using namespace std;
// Определение базового класса
class В {
int i;
public:
void set_i(int n);
int get_i();
};
// Определение производного класса
class D:public В {
int j;
public:
void set_j(int n);
int mul();
};
35. 1.5. Введение в наследование.
// Задание значения i в базовом классеvoid B::set_i(int n){
i = n;
}
// Возвращение значения i в базовом классе
int В::get_i(){
return i;
}
// Задание значения j в производном классе
void D::set_j(int n){
j = n;
}
int D::mul(){
return j * get_i ();
}
36. 1.5. Введение в наследование.
int main() {D ob;
ob.set_i(10);
// загрузка i в базовый класс
ob.set_j(4);
// загрузка j в производный класс
cout << ob.mul();
// вывод числа 40
return 0;
}
Возможные способы доступа к членам класса
Элемент
Объявлен в
классе:
Класс В
Класс D
i
B
private
не доступен
set_i()
B
public
public
get_i()
B
public
public
j
D
—
private
set_j()
D
—
public
mul()
D
—
public
37. 1.5. Введение в наследование. Класс fruit.
#include <iostream>#include <cstring>
using namespace std;
enum yn {no, yes};
enum color {red, yellow, green, orange};
char *c[] = {"red", "yellow", "green", "orange"};
void out(enum yn x);
// Родовой класс фруктов
class fruit {
public:
enum yn tree;
enum yn tropical;
enum color clr;
char name[40];
};
38. 1.5. Введение в наследование. Класс fruit.
// Производный класс яблокclass Apple: public fruit {
enum yn cooking;
enum yn eating;
public:
void seta(char *n, enum color c, enum yn ck,
enum yn crchy, enum yn e) ;
void show();
};
// Производный класс апельсинов
class Orange: public fruit {
enum yn juice;
enum yn sour;
enum yn eating;
public:
void seto(char *n, enum color c, enum yn j,
enum yn sr, enum yn e);
void show();
};
39. 1.5. Введение в наследование. Класс fruit.
void Apple::seta(char *n,{
strcpy(name, n);
tree = yes;
tropical = no;
clr = c;
cooking = ck;
eating = e;
}
enum color c, enum yn ck,
enum yn crchy, enum yn e)
40. 1.5. Введение в наследование. Класс fruit.
void Orange::seto(char *n,{
strcpy(name, n);
tree = yes;
tropical = yes;
clr = c;
juice = j;
sour = sr;
eating = e;
}
enum color c, enum yn j,
enum yn sr, enum yn e)
41. 1.5. Введение в наследование. Класс fruit.
void Apple::show() {cout << name << " яблоко — это: " << "\n";
cout << "Дерево: "; out(tree);
cout << "Тропическое: "; out(tropical);
cout << "Цвет:
" << c[clr] << "\n";
cout << "Легко приготавливается:
"; out(cooking);
cout << "Съедобное:
"; out(eating);
cout << "\n";
}
42. 1.5. Введение в наследование. Класс fruit.
void Orange::show() {cout << name << " апельсин — это: " << "\n";
cout << "Дерево: "; out(tree);
cout << "Тропическое: "; out(tropical);
cout << "Цвет: " << c[clr] << "\n";
cout << "Годится для приготовления сока: "; out(juice);
cout << "Кислый: "; out(sour);
cout << "Съедобный: "; out(eating);
cout << "\n";
}
43. 1.5. Введение в наследование. Класс fruit.
void out(enum yn x) {if (x==no) cout << "нет\n";
else cout << "да\n";
}
int main(int argc, char* argv[])
{
Apple al, a2;
Orange ol, o2;
al.seta("Kpacнaя прелесть", red, no, yes, yes);
a2.seta("Джонатан", red, yes, no, yes);
ol.seto("Пул", orange, no, no, yes);
o2.seto("Baлeнcия", orange, yes, yes, no);
al.show();
a2.show();
ol.show();
o2.show();
return 0;
}
44. 1.5. Введение в наследование. Класс fruit.
Kpacнaя прелесть яблоко — это:Дерево: да
Тропическое: нет
Цвет:
red
Легко приготавливается:
нет
Съедобное:
да
Джонатан яблоко — это:
Дерево: да
Тропическое: нет
Цвет:
red
Легко приготавливается:
Съедобное:
да
да
45. 1.5. Введение в наследование. Класс fruit.
Результат работы программыKpacнaя прелесть яблоко — это: Пул апельсин — это:
Дерево: да
Дерево: да
Тропическое: да
Тропическое: нет
Цвет: orange
Цвет:
red
Легко приготавливается:
нет Годится для приготовления сока:
Кислый: нет
Съедобное:
да
Съедобный: да
Джонатан яблоко — это:
Baлeнcия апельсин — это:
Дерево: да
Дерево: да
Тропическое: нет
Тропическое: да
Цвет:
red
Цвет: orange
Легко приготавливается:
да
Годится для приготовления сока:
Съедобное:
да
Кислый: да
Съедобный: нет
нет
да
46. 1.6. Указатели на объекты.
#include <iostream>using namespace std;
class myclass {
int а;
public:
myclass(int x);
int get();
};
// конструктор
myclass::myclass(int x) {
а = x;
}
int myclass::get() {
return а;
}
47. 1.6. Указатели на объекты.
int main() {myclass ob(120);
// создание объекта
myclass *p;
// создание указателя на объект
p = &ob;
// передача адреса ob в p
cout << "Значение, получаемое через объект:";
cout << ob.get() << "\n";
cout << "Значение, получаемое через указатель:";
cout << p->get() << "\n";
return 0;
}
48. 1.7. Классы, структуры и объединения.
struct имя_типа {// открытые функции и данные — члены класса
private:
// закрытые функции и данные — члены класса
} список_объектов;
union имя_типа {
// открытые функции и данные — члены класса
private:
// закрытые функции и данные — члены класса
} список_объектов;
49. 1.7. Классы, структуры и объединения.
Ограничения, накладываемые на использование объединений:1. объединения не могут наследовать какой бы то ни было класс и не могут
быть базовым классом для любого другого класса;
2. объединения не могут иметь статических членов;
3. объединения не должны содержать объектов с конструктором или
деструктором, хотя сами по себе объединения могут иметь конструкторы и
деструкторы.
50. 1.7. Классы, структуры и объединения.
union { // анонимное объединениеint i ;
char h[4];
};
i = 10;
// непосредственный доступ к переменной i
h[0] = 'X';
// непосредственный доступ к переменной ch
Дополнительные ограничение на использование анонимных объединений:
1. глобальное анонимное объединение должно быть объявлено как
статическое;
2. анонимное объединение не может содержать закрытых членов;
3. имена членов анонимного объединения не должны конфликтовать с другими
идентификаторами той же области видимости.
51. 1.7. Классы, структуры и объединения.
#include <iostream>#include <cstring>
using namespace std;
// использование структуры для определения типа класса
struct st_type {
st_type(double b, char *n);
void show();
private:
double balance;
char.name[40] ;
};
st_type::st_type(double b,
balance = b;
strcpy(name,n);
}
char *n) {
52. 1.7. Классы, структуры и объединения.
void st_type::show() {cout << "Имя:" << name;
cout << ":$" << balance;
if(balance < 0.0) cout << "***";
cout << "\n";
}
int main() {
st_type accl(100.12, "Johnson");
st_type acc2(-12.34, "Hedricks");
accl.show();
acc2.show();
return 0;
}
53. 1.7. Классы, структуры и объединения.
Преобразуем класс strtype в структуру.#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
struct strtype {
strtype(char *ptr);
~strtype();
void show();
private:
char *p;
int len;
};
54. 1.7. Классы, структуры и объединения.
strtype::strtype(char *ptr) {len = strlen(ptr);
p=new char [len];
if(!p)
{
cout << "Ошибка выделения памяти\n";
exit(l);
}
strcpy(p, ptr);
}
strtype::~strtype() {
cout << "Освобождение памяти по адресу p\n";
if (p){
delete [] p;
p=0;
}
}
55. 1.7. Классы, структуры и объединения.
void strtype::show() {cout << p <<"- длина:
cout << "\n";
}
" << len;
int main() {
strtype sl("Это проверка"), s2("Mнe нравится С++");
sl.show();
s2.show();
return 0;
}
56. 1.7. Классы, структуры и объединения.
Использование анонимного объединения для побайтного вывода на экранзначения типа double.
#include <iostream>
using namespace std;
int main() {
union {
unsigned char bytes[8];
double value;
};
int i ;
value = 859345.324;
for(i=0; i<8; i++)
cout << (int) bytes[i]
return 0;
}
<< " ";
57. 1.8. Встраиваемые функции.
// Пример встраиваемой функции#include <iostream>
using namespace std;
inline int even(int x) {
return !(x%2);
}
int main() {
if (even(10)) cout << "10 является четным\n";
if (even(ll)) cout << "11 является четным\n";
return 0;
}
Строки
if (even(10)) cout << "10 является четным\n";
и
if (!(10%2)) cout << "10 является четным\n";
функционально идентичны.
58. 1.8. Встраиваемые функции.
// Демонстрация встраиваемой функции-члена#include <iostream>
using namespace std;
class samp {
int i, j;
public:
samp(int а, int b);
int divisible();
};
samp::samp(int а, int b) {
i = а;
j = b;
}
/* Тело этой функции-члена встраивается в программу*/
inline int samp::divisible() {
return !(i%j);
}
59. 1.8. Встраиваемые функции.
int main() {samp obl(10,2), ob2(10,3);
if(obl.divisible()) cout << "10 делится на 2_\n";
if(ob2.divisible()) cout << "10 делится на 3\n";
return 0;
}
60. 1.8. Встраиваемые функции.
Допускается перегружать встраиваемую функцию.#include <iostream>
using namespace std;
inline int min(int а, int b) {
return а < b ? а: b;
}
inline long min(long а, long b){
return а < b ? а: b;
}
inline double min(double а, double b) {
return а < b ? а: b;
}
int main() {
cout << min(-10, 10) << "\n";
cout << min(-10.01, 100.002) << "\n";
cout << min(-10L, 12L) << "\n";
return 0;
}
61. 1.8.1. Встраиваемые функции в объявлении класса
#include <iostream>using namespace std;
class samp {
int i, j;
public:
samp(int a, int b);
int divisible() {return !(i%j);}
};
samp::samp(int а, int b) {
i = а; j = b;
}
int main () {
sampobl(10,2), ob2(10,3);
if(obl.divisible()) cout << "10 делится на 2\n";
if(ob2.divisible()) cout << "10 делится на 3\n";
return 0;
}
62. 1.8.1. Встраиваемые функции в объявлении класса
Наиболее традиционным использованием встраиваемых функций,определяемых внутри класса, является определение конструктора и
деструктора.
class samp {
int i, j;
public:
// встраиваемый конструктор
samp(int а, int b) {i = а; j = b;}
int divisible() {return !(i%j);}
};
63. 1.8.1. Встраиваемые функции в объявлении класса
Иногда короткие функции могут включаться в объявление класса дажетогда, когда преимущества встраивания мало что дают.
class myclass {
int i;
public:
myclass(int n)
int get_i()
void set_i(int g)
void show()
};
{i = n;}
{return i;}
{i=g;}
{cout << i;}