Синтаксис ООП в С++, примеры классов. Программирование

Содержание

Слайд 2

Объявление класса, создание объекта Создание массива объектов Разделение на объявление и

Объявление класса, создание объекта
Создание массива объектов
Разделение на объявление и реализацию
Использование ключевого

слова this
Конструктор класса
Деструктор класса
Конструктор и создание массивов
Использование ключевого слова const
Конструктор копий
Перегрузка оператора =

Содержание

Программирование

Слайд 3

Объявление класса (можно, например, перед main()): Объявление класса, создание объекта class

Объявление класса (можно, например, перед main()):

Объявление класса, создание объекта

class MyClass {
public:

void Foo () {
printf ("Function Foo from MyClass");
}
};

int main (int argc, char* argv[]) {
MyClass object1;
object1.Foo();
return 0;
}

Программирование

Простое создание и использование объекта:

MyClass* object2 = new MyClass();
object2->Foo();
delete object2;

Динамическое выделение памяти под объект:

в этом месте object1
удаляется автоматически

Слайд 4

Статичный массив: Создание массива объектов MyClass arr[10]; for (int i =

Статичный массив:

Создание массива объектов

MyClass arr[10];
for (int i = 0; i <

10; i++)
arr[i].Foo();

Программирование

MyClass* arr = new MyClass[10];
for (int i = 0; i < 10; i++)
arr[i].Foo();
delete[ ] arr;

Массив с выделением памяти:

инициализируются все 10 объектов

MyClass** arr = new MyClass* [10];
for (int i = 0; i < 10; i++) {
arr[i] = new MyClass();
arr[i]->Foo();
}
for (int i = 0; i < 10; i++)
delete arr[i];
delete[ ] arr;

Массив указателей на объекты с выделением памяти:

10 указателей на объекты

выделение памяти под конкретный объект

удаление объекта

удаление массива

все объекты удаляются вместе с массивом

Слайд 5

В языке C++ удобно разделять объявление и реализацию классов, чтобы использовать

В языке C++ удобно разделять объявление и реализацию
классов, чтобы использовать в

проектах как модули:

Разделение на объявление и реализацию

// файлы класса (можно считать модулем)
myclass.h
myclass.cpp
// точка входа и общие алгоритмы
main.cpp

Программирование

#include
class MyClass {
public:
void Foo();
int GetValue();
private:
int hiddenValue;
};

Объявление класса – содержимое файла myclass.h:

Слайд 6

В языке C++ удобно разделять объявление и реализацию классов, чтобы использовать

В языке C++ удобно разделять объявление и реализацию
классов, чтобы использовать в

проектах как модули:

Разделение на объявление и реализацию

// файлы класса (можно считать модулем)
myclass.h
myclass.cpp
// точка входа и общие алгоритмы
main.cpp

Программирование

#include "myclass.h"
void MyClass::Foo() {
hiddenValue = 42;
printf ("hiddenValue initialized");
}
int MyClass::GetValue() {
return hiddenValue;
}

Реализация методов класса – myclass.cpp:

Слайд 7

В языке C++ удобно разделять объявление и реализацию классов, чтобы использовать

В языке C++ удобно разделять объявление и реализацию
классов, чтобы использовать в

проектах как модули:

Разделение на объявление и реализацию

// файлы класса (можно считать модулем)
myclass.h
myclass.cpp
// точка входа и общие алгоритмы
main.cpp

Программирование

#include
#include "myclass.h"
int main (int argc, char* argv[]) {
MyClass obj;
obj.Foo();
int k = obj.GetValue();
printf ("%d", k);
return 0;
}

Использование класса – main.cpp:

Слайд 8

Можно выделить два типа классов: Условное деление классов по ролям Программирование

Можно выделить два типа классов:

Условное деление классов по ролям

Программирование

1. Основные
Player –

игрок
GameField – игровое поле
Account – банковский счёт

2. Вспомогательные
MyString – работа со строками
MyConfig – настройки
MyDataBase – хранилище данных
MyWeb – работа с Интернетом

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

Слайд 9

В методах класса имена переменных вступают в коллизию: Использование ключевого слова

В методах класса имена переменных вступают в коллизию:

Использование ключевого слова this

class

MyClass {
private:
char buff[100];
int size;
public:
void SetBuff (char *buff, int size) {
this->size = size;
strncpy ( this->buff, buff, size );
this->buff[size] = '\0';
}
};

Программирование

Внутри методов класса this является указателем на экземпляр класса, от имени которого вызван метод.

имена параметров функции
дублируют имена свойств класса

ключевое слово this спешит на помощь

Слайд 10

Автоматическую инициализацию объекта можно выполнить при помощи специальных методов – конструкторов:

Автоматическую инициализацию объекта можно выполнить при помощи специальных методов – конструкторов:

Конструктор

класса

class MyClass {
private:
int* arrBuff;
int size;
public:
MyClass() {
size = 42;
arrBuff = new int[size];
memset( arrBuff, 0, size * sizeof(int) );
}
void SetElement (int index, int value) { arrBuff[index] = value; }
int GetElementAt (int index) { return arrBuff[index]; }
};

Программирование

MyClass intsArray;
intsArray.SetElement(13, 99345);
printf( "%d", intsArray.GetElementAt(13) );
printf( "%d", intsArray.GetElementAt(14) );

Слайд 11

Конструктор с параметрами: Конструктор класса class MyClass { private: int* arrBuff;

Конструктор с параметрами:

Конструктор класса

class MyClass {
private:
int* arrBuff;
int size;
public:
MyClass

(int initSize, int defaultValue = 0) {
size = initSize;
arrBuff = new int[size];
for (int i = 0; i < size; i++)
arrBuff[i] = defaultValue;
}
};

Программирование

MyClass intsArray(10, 42); // 10 элементов со значением 42 каждый
MyClass zeroIntsArray(17); // 17 элементов со значением 0
MyClass* ptrIntsArray = new MyClass(20, 100); // 20 элементов со значением 100
delete ptrIntsArray;

MyClass errArray; //! ОШИБКА: нет конструктора по-умолчанию

Слайд 12

Несколько конструкторов: Конструктор класса class MyClass { private: int* arrBuff; int

Несколько конструкторов:

Конструктор класса

class MyClass {
private:
int* arrBuff;
int size;
public:
MyClass() {

arrBuff = new int[0];
size = 0;
}
MyClass (int initSize, int defaultValue = 0) {
size = initSize;
arrBuff = new int[size];
for (int i = 0; i < size; i++)
arrBuff[i] = defaultValue;
}
};

Программирование

MyClass intsArray(10, 42); // 10 элементов со значением 42
MyClass emptyArray; // вызывается конструктор по-умолчанию

конструктор по-умолчанию гарантирует, что каждый новый объект правильно заполнен на начальном этапе

Слайд 13

Специальный метод, автоматически вызываемый при удалении объекта – деструктор: Деструктор класса

Специальный метод, автоматически вызываемый при удалении объекта – деструктор:

Деструктор класса

class MyClass

{
private:
int* arrBuff;
int size;
public:
MyClass (int initSize) {
size = initSize;
arrBuff = new int[size];
}
~MyClass() {
delete[ ] arrBuff;
}
};

Программирование

int main (int argc, char* argv[]) {
MyClass intsArray(10);
return 0;
}

выделяется память под буфер

удаляется объект, освобождается память

Слайд 14

Если в классе нет конструктора по-умолчанию: Конструктор и создание массивов class

Если в классе нет конструктора по-умолчанию:

Конструктор и создание массивов

class MyClass {
private:

int* arrBuff;
public:
MyClass (int initSize) { arrBuff = new int[initSize]; }
~MyClass() { delete[ ] arrBuff; }
};

Программирование

MyClass arr[10]; //! ОШИБКА: нет конструктора по-умолчанию
MyClass* arr2 = new MyClass[10]; //! ОШИБКА: снова нет конструктора

default конструктора нет, но зато есть конструктор с параметрами

MyClass** arr = new MyClass*[10];
for (int i = 0; i < 10; i++)
arr[i] = new MyClass(15);
// ... полезная работа
for (int i = 0; i < 10; i++)
delete arr[i];
delete[ ] arr;

Слайд 15

При использовании современных языков программирования часто апеллируют к понятию «синтаксический сахар».

При использовании современных языков программирования часто апеллируют к понятию «синтаксический сахар».

«Сахар» упрощает работу программиста, делает её «сладкой», удобной и быстрой.
В C++ «синтаксический сахар» извращённо, мазахистски «сладкий». С привкусом слёз радости от того, что это… наконец скомпилировалось.
С другой стороны, второй столь же гибкий в использовании язык ещё поискать. В правильных руках C++ превращается в недетский такой аттракцион…

Синтаксический сахар

Программирование

Слайд 16

Функция, которая ничего не меняет в объекте: Использование ключевого слова const

Функция, которая ничего не меняет в объекте:

Использование ключевого слова const

class MyClass

{
public:
void DummyFunc() const {
printf ("I will not change this object never ever!");
}
};

class MyClass {
public:
const char* GetString() {
return "One has not to change this string";
}
};

Программирование

Функция, результат которой нельзя менять:

MyClass foo;
char *errStr = foo.GetString(); //! ОШИБКА: нельзя без константы

MyClass foo;
const char *okStr = foo.GetString();

Слайд 17

Функция, параметры которой внутри не поменяются: Использование ключевого слова const class

Функция, параметры которой внутри не поменяются:

Использование ключевого слова const

class MyClass {
public:

void UsefullFunc (int &a) {
a++;
}
void UselessFunc (const int &a) {
a++; //! ОШИБКА: нельзя менять значение
}
};

Программирование

int a = 42;
MyClass val;
val.UsefullFunc(a);
printf ("%d", a); // уже 43
val.UselessFunc(a); // переменная точно не изменится внутри

аналог передачи параметра по указателю, только синтаксически более лучше в использовании

Слайд 18

Полный const: Использование ключевого слова const class MyClass { public: const

Полный const:

Использование ключевого слова const

class MyClass {
public:
const char* TripleComboHit (const

SomeFoo ¶m) const {
...
}
};

Программирование

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

Слайд 19

Особенный конструктор копий для клонирования объектов: Конструктор копий class MyClass {

Особенный конструктор копий для клонирования объектов:

Конструктор копий

class MyClass {
private:
int arr[100];
public:

MyClass () {
/* пустой конструктор */
}
MyClass (const MyClass ©From) {
for (int i = 0; i < 100; i++)
this->arr[i] = copyFrom.arr[i];
}
};

Программирование

MyClass src;
...
MyClass dst (src);

И когда потребуется создать объект на базе другого, то:

конструктор по-умолчанию
нужен для удобства, пусть
даже пустой

тут он как раз и действует

великий и ужасный
конструктор копий

Слайд 20

Вместо клонирования объекта бывает удобнее применить копирование: Перегрузка оператора = class

Вместо клонирования объекта бывает удобнее применить копирование:

Перегрузка оператора =

class MyClass {
private:

int arr[100];
public:
MyClass& operator= (const MyClass ©From) {
if (this == ©From)
return *this;
for (int i = 0; i < 100; i++)
this->arr[i] = copyFrom.arr[i];
return *this;
}
};

Программирование

MyClass src;
...
MyClass dst;
dst = src;

разыменование адреса

по адресу источника определяем,
не пытаемся ли мы себя в себя скопировать