Разделы презентаций


Основы ООП

Содержание

Объектно-ориентированное программированиеПарадигма программирования, основанная на представлении предметной области в виде взаимосвязанных абстрактных объектов и их реализацийОсновными концепциями ООП являются Классы и Объекты

Слайды и текст этой презентации

Слайд 1Основы ООП

Основы ООП

Слайд 2Объектно-ориентированное программирование
Парадигма программирования, основанная на представлении предметной области в виде

взаимосвязанных абстрактных объектов и их реализаций
Основными концепциями ООП являются Классы

и Объекты
Объектно-ориентированное программированиеПарадигма программирования, основанная на представлении предметной области в виде взаимосвязанных абстрактных объектов и их реализацийОсновными концепциями

Слайд 3Классы и объекты
В ООП вводится понятие Класса – пользовательского типа

данных, объединяющего данные и методы их обработки
Класс – тип, описывающий

устройство объекта
Объектом называется экземпляр класса
Собака – это класс
Собака Жучка из 3 подъезда – это объект, представитель или экземпляр класса «Собака»
Чертеж дома – класс, построенный по нему дом - объект
Классы и объектыВ ООП вводится понятие Класса – пользовательского типа данных, объединяющего данные и методы их обработкиКласс

Слайд 4Объявление класса в С++
class
{
// поля класса (данные и

методы)
};

Объявление класса в С++class {	// поля класса (данные и методы)};

Слайд 5Данные объекта (переменные объекта, члены-данные)
Члены-данные (data members) хранят всю необходимую

информацию об объекте, формируют его состояние, характеристики и т.п.
Изменение состояния

объекта или его характеристик связано с изменением данных, в нем содержащихся
Данные объекта (переменные объекта, члены-данные)Члены-данные (data members) хранят всю необходимую информацию об объекте, формируют его состояние, характеристики

Слайд 6Пример
Данными класса «Автомобиль» могут являться
Марка
Год выпуска
Регистрационный номер
Количество топлива в баке
Величина

пробега
Цвет кузова

ПримерДанными класса «Автомобиль» могут являтьсяМаркаГод выпускаРегистрационный номерКоличество топлива в бакеВеличина пробегаЦвет кузова

Слайд 7Методы класса
Класс может содержать один или более методов, позволяющих осуществлять

манипуляцию данными объекта
Метод объекта – программный код, выполненный в виде

процедуры или функции, реагирующий на передачу объекту определенного сообщения
Вызов метода объекта может приводить к изменению его состояния (значение членов-данных), а может и не приводить
Пример 1: поиск и замена текста в документе
Пример 2: проверка правописания текста документа
Методы классаКласс может содержать один или более методов, позволяющих осуществлять манипуляцию данными объектаМетод объекта – программный код,

Слайд 8Пример
Методами класса «Автомобиль» будут являться:
Проехать N километров
Увеличивает пробег, уменьшает топливо
Перекрасить

кузов
Изменяет цвет кузова
Заправить топливо
Увеличивает количество топлива

ПримерМетодами класса «Автомобиль» будут являться:Проехать N километровУвеличивает пробег, уменьшает топливоПерекрасить кузовИзменяет цвет кузоваЗаправить топливоУвеличивает количество топлива

Слайд 9Свойства
Свойство – составляющая часть объекта, доступ к которой осуществляется программистом

как к переменной объекта
В некоторых объектно-ориентированных языках программирования (например, в

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

Слайд 10Пример: Треугольник
Свойства
Координаты вершины A
Координаты вершины B
Координаты вершины C
Площадь
Периметр
Координаты центра вписанной

окружности
Методы
Переместить в заданном направлении
Отмасштабировать
Повернуть вокруг заданной точки

Пример: ТреугольникСвойстваКоординаты вершины AКоординаты вершины BКоординаты вершины CПлощадьПериметрКоординаты центра вписанной окружностиМетодыПереместить в заданном направленииОтмасштабироватьПовернуть вокруг заданной точки

Слайд 11class Point
{
public:
double x, y;
};

class Triangle
{
public:
double GetArea();
double GetPerimeter();
Point GetCenter();

void Move(double dx,

double dy);
void Scale(double sx, double sy);
void Rotate(Point center, double angle);
private:
Point

p0, p1, p2;
};
class Point{public:	double x, y;};class Triangle{public:	double GetArea();	double GetPerimeter();	Point GetCenter();	void Move(double dx, double dy);	void Scale(double sx, double sy);	void Rotate(Point

Слайд 12Важнейшие принципы ООП
Абстракция данных
Инкапсуляция
Наследование
Полиморфизм

Важнейшие принципы ООПАбстракция данныхИнкапсуляцияНаследованиеПолиморфизм

Слайд 13Абстракция данных
Объекты представляют неполную информацию о реальных сущностях предметной области
Абстракция

позволяет оперировать с объектном на уровне, адекватном решаемой задаче
Высокоуровневые обращения

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

Слайд 14Инкапсуляция
Инкапсуляция - способность объекта скрывать внутреннее устройство своих свойств и

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

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

Слайд 15class IntStack
{
public:
void Push(int value);
int Pop();
bool IsEmpty()const;
private:
// здесь располагаются данные
// необходимые

для реализации стека целых чисел
};
Пример. Стек целых чисел

class IntStack{public:	void Push(int value);	int Pop();	bool IsEmpty()const;private:	// здесь располагаются данные	// необходимые для реализации стека целых чисел};Пример. Стек целых

Слайд 16Наследование
Наследование позволяет описать новый класс на основе уже существующего родительского

(базового) класса
Класс-потомок может добавить свои собственные свойства и методы, пользоваться

методами и свойствами базового класса
Наследование позволяет строить иерархии классов
НаследованиеНаследование позволяет описать новый класс на основе уже существующего родительского (базового) классаКласс-потомок может добавить свои собственные свойства

Слайд 17Пример
class Plane
{
public:
void TakeOff();
void Fly();
void Land();
private:
double m_fuel;
};

class MilitaryPlane : public Plane
{
public:
void

Attack();
private:
int m_ammo;
};

Примерclass Plane{public:	void TakeOff();	void Fly();	void Land();private:	double m_fuel;};class MilitaryPlane : public Plane{public:	void Attack();private:	int	m_ammo;};

Слайд 18Полиморфизм
Полиморфизмом называют явление, при котором классы-потомки могут изменять реализацию метода

класса-предка, сохраняя его интерфейс
Полиморфизм позволяет обрабатывать объекты классов-потомков как однотипные

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

Слайд 19class Shape
{
public:
virtual double GetArea()=0;
};

class Rectangle : public Shape
{
public:
virtual double GetArea()
{
return

width * height;
}
private:
double width, height;
};

class Circle : public Shape
{
public:
virtual double GetArea()
{
return

3.1415927 * radius * radius;
}
private:
double radius;
};
class Shape{public:	virtual double GetArea()=0;};class Rectangle : public Shape{public:	virtual double GetArea()	{		return width * height;	}private:	double	width, height;};class Circle : public

Слайд 20Объявление класса в C++
Для объявления класса в C++ служит ключевое

слово class
Синтаксис
class идентификатор { // объявление данных и методов };
Реализация методов

класса может быть вынесена за пределы объявления класса
Объявление класса в C++Для объявления класса в C++ служит ключевое слово classСинтаксисclass идентификатор {   //

Слайд 21Пример
class Date
{
public:
void Next();
void Print()const;
private:
int year, month, day;
};

// Реализация методов класса
void

Date::Print()const
{
std::cout

year << "\n";
}

void Date::Next()
{
// ...
}
Примерclass Date{public:	void Next();	void Print()const;private:	int year, month, day;};// Реализация методов классаvoid Date::Print()const{	std::cout

Слайд 22Размещение классов в различных файлах
Общепринятой практикой является размещение объявления классов

в заголовочных файлах .h, а их реализации – в файлах

.cpp
Повышение модульности проекта
Каждый класс может быть подключен для дальнейшего использования при помощи директивы #include “имя заголовочного файла”
При внесении изменений в реализацию метода класса перекомпиляции подвергнутся только измененные файлы
Размещение классов в различных файлахОбщепринятой практикой является размещение объявления классов в заголовочных файлах .h, а их реализации

Слайд 23Пример
date.h


class Date
{
public:
void Next();
void Print()const;
...
private:
int m_day;
int m_month;
int m_year;
};
date.cpp


#include “date.h”

void Date::Next()
{
// ...
}

void

Date::Print()const
{
// ...
}
...
main.cpp


#include “date.h”

int main()
{
Date date1;
...
return 0;
}

Примерdate.hclass Date{public:	void Next();	void Print()const;	...private:	int m_day;	int m_month;	int m_year;};date.cpp#include “date.h”void Date::Next(){	// ...}void Date::Print()const{	// ...}...main.cpp#include “date.h”int main(){	Date date1;	...	return 0;}

Слайд 24Ограничение доступа к данным и методам класса
Доступ к данным и

методам класса извне может быть ограничен
Рекомендуется запрещать доступ к данным

класса в обход его методов
Для разделения прав доступа к полям класса используются ключевые слова
public:
private:
protected:
Ограничение доступа к данным и методам классаДоступ к данным и методам класса извне может быть ограниченРекомендуется запрещать

Слайд 25Публичные (public) поля класса
Public-методы и данные класса определяют его интерфейс
доступ

к ним возможен из любой части кода
необходимо помещать в public-раздел

класса только необходимый набор методов, выполняющих высокоуровневые операции над объектом класса
Публичные (public) поля классаPublic-методы и данные класса определяют его интерфейсдоступ к ним возможен из любой части коданеобходимо

Слайд 26Закрытые (частные) поля класса
Private-данные и методы класса определяют его реализацию
Доступ

к ним разрешен только из методов данного класса
Рекомендуется все данные

класса делать закрытыми, их обработку осуществлять внутри методов
Закрытые методы класса обычно используются публичными и защищенными методами, решая внутренние задачи класса
Закрытые (частные) поля классаPrivate-данные и методы класса определяют его реализациюДоступ к ним разрешен только из методов данного

Слайд 27Защищенные поля класса
Protected-данные и методы определяют интерфейс для производных классов
Доступ

к ним разрешен изнутри методов данного класса и всех его

потомков
В защищенной зоне размещают методы, которые не должны быть видны снаружи класса, но реализация которых может быть переопределена или использована производными классами
Защищенные поля классаProtected-данные и методы определяют интерфейс для производных классовДоступ к ним разрешен изнутри методов данного класса

Слайд 28Уровни доступа к полям и методам класса

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

Слайд 29Пример
// Просто "человек"
class CPerson
{
public:
// Потратить заданную сумму денег
bool SpendMoney(int amount)
{
//

Нельзя потратить отрицательное количество денег или больше,
// чем имеется в

наличии
if (amount < 0 || amount > GetMoneyAmount())
{
return false;
}
SpendMoneyImpl(amount);
return true;
}

// Фактическая реализация метода получения количества денег
// будет переопределена в классах-наследниках
virtual int GetMoneyAmount()const = 0;
protected:
// Фактическая реализация метода траты денег будет переопределена
// в классах-наследниках
virtual void SpendMoneyImpl(int amount) = 0;
}

Слайд 30Школьник
// Школьник
class CPupil : public CPerson
{
public:
CPupil():m_moneyForSweets(100){}
virtual int GetMoneyAmount()const
{
// Из всех

денег - только деньги на сладости
return m_moneyForSweets;
}
protected:
virtual void SpendMoneyImpl(int amount)
{
//

Эти же деньги он и может потратить
assert(amount <= m_moneyForSweets);
m_moneyForSweets -= amount;
}
private:
int m_moneyForSweets;
};
Школьник// Школьникclass CPupil : public CPerson{public:	CPupil():m_moneyForSweets(100){}	virtual int GetMoneyAmount()const	{		// Из всех денег - только деньги на сладости		return m_moneyForSweets;	}protected:	virtual

Слайд 31Студент
class CStudent : public CPerson
{
public:
CStudent():m_moneyForBeer(100),m_moneyForFood(100),m_moneyForGirls(100){}
virtual int GetMoneyAmount()const
{ // У студента деньги

формируются из нескольких "заначек"
return m_moneyForBeer + m_moneyForFood + m_moneyForGirls;
}
protected:
virtual void

SpendMoneyImpl(int amount)
{ // сперва тратим деньги, отложенные на пиво
const int beerMoney = std::min(amount, m_moneyForBeer);
m_moneyForBeer -= beerMoney; amount -= beerMoney;

// затем придется тратить деньги, отложенные на девушку
const int girlMoney = std::min(amount, m_moneyForGirls);
m_moneyForGirls -= girlMoney; amount -= girlMoney;

// остаток будем тратить из запасов на еду
assert(amount <= m_moneyForFood);
m_moneyForFood -= amount;
}
private:
int m_moneyForBeer, m_moneyForGirls, m_moneyForFood;
};
Студентclass CStudent : public CPerson{public:	CStudent():m_moneyForBeer(100),m_moneyForFood(100),m_moneyForGirls(100){}	virtual int GetMoneyAmount()const	{	// У студента деньги формируются из нескольких

Слайд 32Аспирант
class CAdvancedStudent : public CStudent
{
public:
CAdvancedStudent():m_moneyForThesis(100){}
virtual int GetMoneyAmount()const
{ // Денег столько же,

сколько есть у студента + деньги на защиту диссертации
return CStudent::GetMoneyAmount()

+ m_moneyForThesis;
}
protected:
virtual void SpendMoneyImpl(int amount)
{
int studentMoney = CStudent::GetMoneyAmount();
if (studentMoney < amount)
{
// придется взять часть денег из диссертации
int thesisMoney = amount - studentMoney;
m_moneyForThesis -= thesisMoney; amount -= thesisMoney;
}
// Остальное тратим, как потратил бы студент
CStudent::SpendMoneyImpl(amount);
}
private:
int m_moneyForThesis;
};
Аспирантclass CAdvancedStudent : public CStudent{public:	CAdvancedStudent():m_moneyForThesis(100){}	virtual int GetMoneyAmount()const	{	// Денег столько же, сколько есть у студента + деньги на

Слайд 33Ссылка на себя
Внутри методов класса для обращения к данным класса

можно использовать их имена
В метод класса неявно передается указатель на

объект, для которого он вызывается
Доступен данный указатель по ключевому слову this
Ссылка на себяВнутри методов класса для обращения к данным класса можно использовать их именаВ метод класса неявно

Слайд 34Пример
class ListItem
{
public:
void Append(ListItem *pItem)
{
pItem->m_pNext = this;
m_pPrevious = pItem;
m_pNext = NULL;
}
private:
ListItem

*m_pNext;
ListItem *m_pPrevious;
int m_data;
};

Примерclass ListItem{public:	void Append(ListItem *pItem)	{		pItem->m_pNext = this;		m_pPrevious = pItem;		m_pNext = NULL;	}private:	ListItem *m_pNext;	ListItem *m_pPrevious;	int		m_data;};

Слайд 35Константные методы
В языке C++ методы объекта, не изменяющие его состояния

(его данных) могут быть объявлены константными
Например, методы, возвращающие значения определенных

полей данных
Изменить данные класса из константного метода нельзя
Константные методыВ языке C++ методы объекта, не изменяющие его состояния (его данных) могут быть объявлены константнымиНапример, методы,

Слайд 36Когда возникает необходимость в константных методах
Если объект был объявлен как

константа, либо доступен по константной ссылке или указателю на const,

то вызвать у него можно только константные методы
Это заставляет объявлять методы константными везде, где это только возможно

Когда возникает необходимость в константных методахЕсли объект был объявлен как константа, либо доступен по константной ссылке или

Слайд 37Пример
class IntArray
{
public:

int GetSize()const
{
return m_numberOfItems;
}
void ClearElements()
{
delete [] m_pData;
m_pData = NULL;
m_numberOfItems =

0;
}
private:
int *m_pData;
int m_numberOfItems;
};

void f(IntArray const& array)
{
int i = array.GetSize(); // можно
array.ClearElements(); //

нельзя – неконстантные методы недоступны
}
Примерclass IntArray{public:	…	int GetSize()const	{		return m_numberOfItems;	}	void ClearElements()	{		delete [] m_pData;		m_pData = NULL;		m_numberOfItems = 0;	}private:	int *m_pData;	int m_numberOfItems;};void f(IntArray const& array){	int i

Слайд 38Изменчивые (mutable) данные класса
Данные класса, которые все-таки нужно изменять из

константных методов класса в С++ объявляются с ключевым словом mutable
Пользоваться

этой возможностью следует аккуратно, четко осознавая, что даже в этом случае константные методы не должны изменять состояние объекта
Под состоянием объекта здесь понимается информация о нем, доступная посредством публичных методов
Изменчивые (mutable) данные классаДанные класса, которые все-таки нужно изменять из константных методов класса в С++ объявляются с

Слайд 39Пример
class VeryComplexShape
{
public:
VeryComplexShape()
{
m_areaInitialized = false;
}
double GetArea()const
{
if (!m_areaInitialized)
{
// вычисляем площадь фигуры (задача

требует длительных вычислений)
m_areaInitialized = true;

}
return m_area;
}
void ModifyShape(...)
{
m_areaInitialized = false;
// ...
}
private:
mutable

bool m_areaInitialized;
mutable double m_area;
};
Примерclass VeryComplexShape{public:	VeryComplexShape()	{		m_areaInitialized = false;	}	double GetArea()const	{		if (!m_areaInitialized)		{			// вычисляем площадь фигуры (задача требует длительных вычислений)			m_areaInitialized = true;			…		}		return m_area;	}	void ModifyShape(...)	{		m_areaInitialized

Слайд 40Инициализация экземпляра класса
Для инициализации состояния объекта в момент его создания

существует специальная функция – конструктор
Конструктор имеет то же имя, что

и имя класса
Тип возвращаемого значения для конструктора не указывается (даже void)
Конструктор вызывается один в момент создания экземпляра класса (объявление переменной класса или вызов оператора new)
Класс может иметь несколько конструкторов, предоставляющих различные способы инициализации объекта
Для инициализации объекта может быть вызван только один из них
Инициализация экземпляра классаДля инициализации состояния объекта в момент его создания существует специальная функция – конструкторКонструктор имеет то

Слайд 41Пример
class Date
{
public:
Date(int day, int month)
{
m_day = day;
m_month = month;
m_year

= GetCurrentYear();
}
Date(int day, int month, int year)
{
m_day = day;
m_month =

month;
m_year = year;
}
private:
int m_day, m_month, m_year;
};
Примерclass Date{public:	Date(int day, int month)	{		m_day = day;		m_month = month; 		m_year = GetCurrentYear();	}	Date(int day, int month, int year)	{		m_day

Слайд 42Конструктор по умолчанию
Конструктор, не имеющий параметров, называется конструктором по умолчанию
Поля

данных в таком конструкторе инициализируются значениями по умолчанию
Создавать такой конструктор

или не создавать – зависит от конкретной задачи
Конструктор по умолчаниюКонструктор, не имеющий параметров, называется конструктором по умолчаниюПоля данных в таком конструкторе инициализируются значениями по

Слайд 43Инициализация данных экземпляра класса
В качестве данных класса могут выступать другие

классы
Их инициализация осуществляется ДО выполнения тела конструктора
Для их инициализации вызываются

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

Слайд 44Списки инициализации
Применяются для инициализации полей класса в конструкторе ДО выполнения

его тела
Использование списков инициализации – единственное решение в случае, когда

класс содержит внутри себя
поля, являющиеся классами без конструкторов по умолчанию
константы
ссылки
Списки инициализацииПрименяются для инициализации полей класса в конструкторе ДО выполнения его телаИспользование списков инициализации – единственное решение

Слайд 45Пример
class CDocument
{
public:
void Open(string const& fileName);
void Save(string const& fileName)const;
// Прочие операции

на документом
};

class CEditor
{
public:
CEditor(CDocument & document)
:m_document(document)
{
}
void Undo();
void Redo();
void ReplaceText(
size_t offset, size_t

length,
string const& text);
// Прочие операции редактора
// …
private:
CDocument & m_document;
};

int main(int argc, char * argv[])
{
CDocument document;
document.Open("fileName.doc");

CEditor editor(document);

// Вызываем операции редактора документа
// …

document.Save("fileName1.doc");

return 0;
}

Примерclass CDocument{public:	void Open(string const& fileName);	void Save(string const& fileName)const;	// Прочие операции на документом	};class CEditor{public:	CEditor(CDocument & document)		:m_document(document)	{	}	void Undo();	void Redo();	void

Слайд 46Деинициализация экземпляра класса
В ходе своей работы объект может использовать определенные

системные ресурсы
Динамическая память, открытые файлы, сетевые соединения и т.п.
При разрушении

объекта используемые им единолично ресурсы должны освобождаться
В C++ для освобождения этих ресурсов служит особый метод класса – деструктор
Деинициализация экземпляра классаВ ходе своей работы объект может использовать определенные системные ресурсыДинамическая память, открытые файлы, сетевые соединения

Слайд 47Деструктор
Имя деструктора совпадает с именем класса, только перед ним указывается

символ ~ (тильда)
Данный метод вызывается автоматически при уничтожении экземпляра класса:
Выход

за пределы блока, в котором объявлен экземпляр класса
Вызов оператора delete или delete []
ДеструкторИмя деструктора совпадает с именем класса, только перед ним указывается символ ~ (тильда)Данный метод вызывается автоматически при

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

жизненный цикл объекта
Освобождение выделенных объектом ресурсов
Что-нибудь еще

Содержимое тела деструктораВ деструкторе программист размещает код, выполняющий действия, завершающие жизненный цикл объектаОсвобождение выделенных объектом ресурсовЧто-нибудь еще

Слайд 49Пример
class MyFile
{
public:
MyFile():m_pFile(NULL)
{}
~MyFile()
{
Close();
}
bool Open(const char *fileName)
{
Close();
m_pFile = fopen(fileName, “r”);
return m_pFile !=

NULL;
}
void Close()
{
if (m_pFile)
{
fclose(m_pFile);m_pFile = NULL;
}
}
...
private:
FILE *m_pFile;
};
int main(int argc, char *

argv[])
{
MyFile file;
if (file.Open("text.txt"))
{
// Выполняем операции над файлом
}

MyFile * pFile = new MyFile();
...
// вызов деструктора и освобождение
// памяти, занимаемой объектом pFile
// в куче
delete pFile;
pFile = NULL;

return 0;
} // При выходе из данного блока
// будет вызван деструктор объекта file

Примерclass MyFile{public:	MyFile():m_pFile(NULL)	{}	~MyFile()	{		Close();	}	bool Open(const char *fileName)	{		Close();		m_pFile = fopen(fileName, “r”);		return m_pFile != NULL;	}	void Close()	{		if (m_pFile)		{			fclose(m_pFile);m_pFile = NULL;		}	}	...private:	FILE *m_pFile;};int main(int

Слайд 50Жизнь после смерти
В C++ после выполнения тела деструктора происходит автоматический

вызов деструкторов членов-данных класса
Порядок вызова деструкторов обратен порядку объявления
Если класс

был унаследован от другого класса, будет вызван деструктор родительского класса
И т.д. по цепочке
После этого происходит освобождение занимаемой объектом памяти
Жизнь после смертиВ C++ после выполнения тела деструктора происходит автоматический вызов деструкторов членов-данных классаПорядок вызова деструкторов обратен

Слайд 51Класс «Колесо»
class Wheel
{
public:
Wheel(string const& name)
:m_name(name)
{
cout

m_name

"\n";
}
private:
string m_name;
};
Класс «Колесо»class Wheel{public:	Wheel(string const& name)		:m_name(name)	{		cout

Слайд 52Класс «Автомобиль»
class Car
{
public:
Car(string const& name):m_name(name)
,m_frontRight("Front right“),m_rearLeft("Rear left")
,m_rearRight("Rear right“),m_frontLeft("Front left")
{
cout

"Constructing car "

<< "Destroying car " << m_name << "\n";
}
private:
string m_name;
Wheel m_frontLeft;
Wheel m_frontRight;
Wheel m_rearLeft;
Wheel m_rearRight;
};
Класс «Автомобиль»class Car{public:	Car(string const& name):m_name(name)		,m_frontRight(

Слайд 53Класс «Супер автомобиль»
class SuperCar : public Car
{
public:
SuperCar(string const& name)
:Car(name)
,m_fifthWheel("Fifth wheel")
{
cout

"Destroying super car " << GetName() << "\n";
}
private:
Wheel m_fifthWheel;
};
Класс «Супер автомобиль»class SuperCar : public Car{public:	SuperCar(string const& name)		:Car(name)		,m_fifthWheel(

Слайд 54Порядок вызова конструкторов и деструкторов
int main(int argc, char* argv[])
{
SuperCar ladaKalina("Lada

Kalina");

return 0;
}
Constructing wheel Front left
Constructing wheel Front right
Constructing wheel Rear

left
Constructing wheel Rear right
Constructing car Lada Kalina
Constructing wheel Fifth wheel
Constructing super car Lada Kalina
Destroying super car Lada Kalina
Destroying wheel Fifth wheel
Destroying car Lada Kalina
Destroying wheel Rear right
Destroying wheel Rear left
Destroying wheel Front right
Destroying wheel Front Left

Конструирование полей базового класса Car

Выполнение тела конструктора класса Car

Конструирование полей класса SuperCar

Тело конструктора класса SuperCar

Тело деструктора класса SuperCar

Деструкторы полей полей класса SuperCar

Тело деструктора класса Car

Разрушение полей класса SuperCar

Output:

Порядок вызова конструкторов и деструкторовint main(int argc, char* argv[]){	SuperCar ladaKalina(

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

объявлен деструктор
Автоматически сгенерированный конструктор имеет пустое тело
Остальные механизмы разрушения объекта

работают обычным образом
Деструктор
Разрушение указателя не выполняет освобождения памяти, на который он ссылается
Автоматически сгенерированный деструкторСоздается компилятором, если в классе не был явно объявлен деструкторАвтоматически сгенерированный конструктор имеет пустое телоОстальные

Слайд 56Корректно работающий автоматически сгенерированный деструктор
class CDataBase
{
public:
private:
std::string m_databaseName;
MyFile m_databaseFile;
};
При разрушении экземпляра

класса CDataBase деструкторы содержащихся в нем объектов освободят занимаемую память

Корректно работающий автоматически сгенерированный деструкторclass CDataBase{public:private:	std::string m_databaseName;	MyFile m_databaseFile;};При разрушении экземпляра класса CDataBase деструкторы содержащихся в нем объектов

Слайд 57Некорректно работающий автоматически сгенерированный деструктор
class CDataBase
{
public:
void DoSomething()
{
m_bufferArray = new int[100];
}
private:
int

* m_bufferArray;
std::string m_databaseName;
MyFile m_databaseFile;
};
Автоматически сгенерированный деструктор не выполнит удаление массива

m_bufferArray
Некорректно работающий автоматически сгенерированный деструкторclass CDataBase{public:	void DoSomething()	{		m_bufferArray = new int[100];	}private:	int * m_bufferArray;	std::string m_databaseName;	MyFile m_databaseFile;};Автоматически сгенерированный деструктор не

Слайд 58Копирование объектов

Копирование объектов

Слайд 59Конструктор копирования (копирующий конструктор)
В языке C++ существует специальный тип конструкторов,

использующийся для создания копии объекта
Явное создание копии объекта программистом
Неявное создание

копии объекта
Возврат объекта из функции
Передача объекта в функцию по значению
Во время работы механизма исключений
Синтаксис
Type(Type const& t);
Конструктор копирования (копирующий конструктор)В языке C++ существует специальный тип конструкторов, использующийся для создания копии объектаЯвное создание копии

Слайд 60Автоматически сгенерированный конструктор копирования
Если программист не определит конструктор копирования явно,

компилятор сгенерирует его во время компиляции
Автоматически сгенерированный конструктор копирования осуществляет

копирование всех полей класса, вызывая для них их конструкторы копирования
Автоматически сгенерированный конструктор копированияЕсли программист не определит конструктор копирования явно, компилятор сгенерирует его во время компиляцииАвтоматически сгенерированный

Слайд 61#include "stdio.h"

class Foo
{
public:
Foo():m_moo(0)
{
}
Foo(Foo const& foo) :m_moo(foo.m_moo)
{
std::cout

foo\n";
}
private:
int m_moo;
};
class Bar
{
public:
void Do()
{
std::cout

<< "g()\n";
Bar b;
return b;
}

int main()
{
Bar b0;
std::cout << "Call f()\n";
f(b0);
std::cout << "Call g()\n";
Bar b1 = (g());
b1.Do();
return 0;
}

OUTPUT:
Call f()
Creating copy of foo
f()
Do
Call g()
g()
Creating copy of foo
Do

#include

Слайд 62Создание собственного конструктора копирования
Часто возникают ситуации, когда автоматически сгенерированный конструктор

копирования не подходит
Пример – класс, реализующий массив
Стандартный конструктор копирования просто

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

Слайд 63Пример
#include "stdio.h"
#include "memory.h"

class IntArray
{
public:
IntArray():m_pData(NULL), m_size(0){}

IntArray(IntArray const& arr)
:m_pData(new int [arr.m_size])
,m_size(arr.m_size)
{
if (m_size

!= 0)
{
memcpy(m_pData, arr.m_pData, sizeof(int) * m_size);
}
}

private:
int * m_pData;
int m_size;
};


Слайд 64Запрещение копирования объектов
Возможны ситуации, когда операция копирования объекта не имеет

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

с файлом
Объект должен существовать в единственном экземпляре внутри приложения, например, «клавиатура»
Для запрещения копирования объекта, конструктор копирования объявляется в закрытой (private) области класса
Реализацию данного конструктора можно не писать
Запрещение копирования объектовВозможны ситуации, когда операция копирования объекта не имеет смысла и должна быть запрещенаКласс, инкапсулирующий сетевое

Слайд 65Пример
class CFile
{
public:
// …
private:
CFile(CFile const&);
// …
};

Примерclass CFile{public:	// …private:	CFile(CFile const&);	// …};

Слайд 66Статические данные и методы класса

Статические данные и методы класса

Слайд 67Для чего нужны статические данные класса
Класс – это тип данных
Для

каждого объекта создается своя собственная копия членов данных
Методы класса работают

с одним из экземпляров класса, на которые ссылается this
Для некоторых классов естественными могли бы оказаться данные, общие для всех экземпляров данного класса
Например, строковое представление имени класса
Константы, общие для всех экземпляров класса, область видимости которых должна быть ограничена методами класса
Такие поля и методы называют статическими и объявляют при помощи ключевого слова static
Для чего нужны статические данные классаКласс – это тип данныхДля каждого объекта создается своя собственная копия членов

Слайд 68Особенности
Статические методы не получают указатель this
Статические методы могут обращаться только

к статическим данным класса
Статические методы могут вызывать только статические методы
Либо

нестатические, если им передается указатель или ссылка на объект класса
Статические методы имеют доступ к закрытым и защищенным полям и методам класса, через экземпляры классов
Доступ к статическим методам и данным класса осуществляется по имени класса (создавать экземпляр не требуется)
ОсобенностиСтатические методы не получают указатель thisСтатические методы могут обращаться только к статическим данным классаСтатические методы могут вызывать

Слайд 69Пример
Foo.h:
class Foo
{
public:
static std::string const GetClassName()
{
return m_className;
}
private:
static std::string const m_className;
};

Foo.cpp:
#include "Foo.h"
std::string

const Foo::m_className = "Foo";

main.cpp:
#include "foo.h"
int main(int argc, char *argv[])
{
std::cout

Foo::GetClassName() << "\n";
return 0;
}
ПримерFoo.h:class Foo{public:	static std::string const GetClassName()	{		return m_className;	}private:	static std::string const m_className;};Foo.cpp:#include

Слайд 70Область применения
Запрещение создания объектов в области стека
Приватный конструктор + статический

метод для создания класса в куче
Паттерн «одиночка» (singleton)
Объект с глобальным

доступом, существующий в программе в единственном экземпляре
Методы и данные, характерные для класса в целом, а не для отдельных его экземпляров
Создание классов-утилит
Классы, состоящие исключительно из статических методов
Область примененияЗапрещение создания объектов в области стекаПриватный конструктор + статический метод для создания класса в кучеПаттерн «одиночка»

Слайд 71Пример – паттерн «Одиночка»
// singleton.h
class Singleton
{
public:
static Singleton & GetInstance()
{
if (!m_pInstance)
{
m_pInstance

= new Singleton();
}
return *m_pInstance;
}
void SomeMethod(){}
private:
Singleton(){}
static Singleton *m_pInstance;
};
// singleton.cpp
Singleton* Singleton::m_pInstance =

NULL;

int main(int argc, char * argv[])
{
Singleton& singleton = Singleton::GetInstance();
singleton.SomeMethod();
return 0;
}
Пример – паттерн «Одиночка»// singleton.hclass Singleton{public:	static Singleton & GetInstance()	{		if (!m_pInstance)		{			m_pInstance = new Singleton();		}		return *m_pInstance;	}	void SomeMethod(){}private:	Singleton(){}	static Singleton *m_pInstance;};//

Слайд 72Пример – создание объектов только в динамической памяти
class CFile
{
public:
static boost::shared_ptr

Open(std::string const& fileName)
{
boost::shared_ptr pFile(new CFile());
if (!pFile->OpenFile(fileName))
{
pFile.reset();
}
return pFile;
}
static boost::shared_ptr Create(std::string const&

fileName)
{
boost::shared_ptr pFile(new CFile());
if (!pFile->CreateFile(fileName))
{
pFile.reset();
}
return pFile;
}
private:
CFile(){...}
bool OpenFile(
string const& fileName){...}
bool CreateFile(
string const& fileName){...}
};

int main(int argc, char * argv[])
{
boost::shared_ptr pFile =
CFile::Open("filename.txt");

if (pFile)
{
...
}
return 0;
}

Пример – создание объектов только в динамической памятиclass CFile{public:	static boost::shared_ptr Open(std::string const& fileName)	{		boost::shared_ptr pFile(new CFile());		if (!pFile->OpenFile(fileName))		{			pFile.reset();		}		return pFile;	}	static

Слайд 73Вложенные классы

Вложенные классы

Слайд 74Вложенное объявление классов и других типов данных
Язык C++ позволяет разместить

объявление одного класса (или другого типа данных) внутри объявления другого
Это

полезно, когда вложенный тип данных используется лишь внешним классом, или совместно с ним
Пример - итераторы стандартных контейнеров STL
Использование вложенного класса
Из методов внешнего класса – по имени вложенного класса
Снаружи – при помощи указания имени внешнего класса:
ExternalClass::Internal
Вложенное объявление классов и других типов данныхЯзык C++ позволяет разместить объявление одного класса (или другого типа данных)

Слайд 75Пример 1
class External
{
public:
class Internal
{
public:
void Foo(){}
};
private:
void Bar()
{
// из методов внешнего

класса можем обращаться по имени
Internal internal;
internal.Foo();
}
};

int main(int argc, char* argv[])
{
External::Internal

internal;
internal.Foo();
return 0;
}
Пример 1class External{public:	class Internal	{	public:		void Foo(){}	};private:	void Bar()	{		 // из методов внешнего класса можем обращаться по имени		Internal internal;		internal.Foo();	}};int main(int

Слайд 76Пример 2 – идиома «Pimpl»
// ComplexClass.h
class CComplexClass
{
public:
CComplexClass();
void Foo();
~CComplexClass();
private:
//

класс Impl хранит все
// приватные данные и методы
// класса CComplexClass
class

Impl;
Impl * m_pImpl;
};

// ComplexClass.cpp
class CComplexClass::Impl
{
public:
void Foo()
{
//…
}
private:
// …
};

CComplexClass::CComplexClass()
:m_pImpl(new Impl())
{
}

CComplexClass::~CComplexClass()
{
delete m_pImpl;
}

void CComplexClass::Foo()
{
m_pImpl->Foo();
}

Данный подход позволяет в языке C++ сократить количество зависимостей времени компиляции от модификации приватной части класса, т.к. она фактически вынесена из заголовочного файла в .CPP файл

Пример 2 – идиома «Pimpl»// ComplexClass.hclass CComplexClass{public:	CComplexClass();  void Foo();	~CComplexClass();private:	// класс Impl хранит все	// приватные данные и

Обратная связь

Если не удалось найти и скачать доклад-презентацию, Вы можете заказать его на нашем сайте. Мы постараемся найти нужный Вам материал и отправим по электронной почте. Не стесняйтесь обращаться к нам, если у вас возникли вопросы или пожелания:

Email: Нажмите что бы посмотреть 

Что такое TheSlide.ru?

Это сайт презентации, докладов, проектов в PowerPoint. Здесь удобно  хранить и делиться своими презентациями с другими пользователями.


Для правообладателей

Яндекс.Метрика