Презентация ООП 8. Варианты наследования онлайн
На нашем сайте вы можете скачать и просмотреть онлайн доклад-презентацию на тему ООП 8. Варианты наследования абсолютно бесплатно. Урок-презентация на эту тему содержит всего 25 слайдов. Все материалы созданы в программе PowerPoint и имеют формат ppt или же pptx. Материалы и темы для презентаций взяты из открытых источников и загружены их авторами, за качество и достоверность информации в них администрация сайта не отвечает, все права принадлежат их создателям. Если вы нашли то, что искали, отблагодарите авторов - поделитесь ссылкой в социальных сетях, а наш сайт добавьте в закладки.
Презентации » Устройства и комплектующие » ООП 8. Варианты наследования
Оцените!
Оцените презентацию от 1 до 5 баллов!
- Тип файла:ppt / pptx (powerpoint)
- Всего слайдов:25 слайдов
- Для класса:1,2,3,4,5,6,7,8,9,10,11
- Размер файла:345.00 kB
- Просмотров:57
- Скачиваний:0
- Автор:неизвестен
Слайды и текст к этой презентации:
№2 слайд
![Проблема неоднозначности](/documents_6/f77a24940abb0149e0193c24303cadd8/img1.jpg)
Содержание слайда: Проблема неоднозначности
class BorrowableItem { // нечто, что можно позаимствовать из библиотеки
public:
void checkOut();
...
};
class ElectronicGadget {
private:
bool checkOut() const; // выполняет самотестирование, возвращает
// признак успешности теста
...
};
class MP3Player: public BorrowableItem, public ElectronicGadget {...}
/* здесь множественное наследование (в некоторых библиотеках реализована функциональность, необходимая для MP3-плееров) */
MP3Player mp;
mp.checkout(); // неоднозначность! какой checkOut?
mp.ElectronicGadget::checkOut() // ошибка! Попытка вызвать закрытый метод
mp.BorrowableItem::checkOut(); // вот какая checkOut нужна!
№4 слайд
![Виртуальное наследование](/documents_6/f77a24940abb0149e0193c24303cadd8/img3.jpg)
Содержание слайда: Виртуальное наследование
class File {...}; // виртуальный базовый класс
class InputFile: virtual public File {...};
class OutputFile: virtual public File {...};
class IOFile: public InputFile, public OutputFile {...};
/*все непосредственные потомки используют виртуальное наследование */
№5 слайд
![В стандартной библиотеке C](/documents_6/f77a24940abb0149e0193c24303cadd8/img4.jpg)
Содержание слайда: В стандартной библиотеке C++ есть похожая иерархия, только классы в ней являются шаблонными и называются basic_ios, basic_istream, basic_ ostream и basic_iostream.
Виртуальное наследование требует затрат.
Размер объектов классов обычно оказывается больше, а доступ к полям виртуальных базовых классов медленнее.
Если избежать виртуальных базовых классов не удаётся, старайтесь не размещать в них данных. (Аналог: интерфейсы Java и. NET)
№6 слайд
![Ответственность за](/documents_6/f77a24940abb0149e0193c24303cadd8/img5.jpg)
Содержание слайда: Ответственность за инициализацию виртуального базового класса ложится на самый дальний производный класс в иерархии. Отсюда следует, что:
(1) классы, наследующие виртуальному базовому и требующие инициализации, должны знать обо всех своих виртуальных базовых классах, независимо от того, как далеко они от них находятся в иерархии
(2) когда в иерархию добавляется новый производный класс, он должен принять на себя ответственность за инициализацию виртуальных предков (как прямых, так и непрямых).
/* конструктор IOFile должен вызывать конструкторы
File, затем InputFile и OutputFile*/
№7 слайд
![Пример интерфейсного класса](/documents_6/f77a24940abb0149e0193c24303cadd8/img6.jpg)
Содержание слайда: Пример интерфейсного класса
class IPerson {
public:
virtual ~IPerson();
virtual std::string name() const = 0;
virtual std::string birthDate() const = 0;
}; /*Пользователи IPerson должны программировать в терминах указателей и ссылок на IPerson, поскольку создавать объекты абстрактных классов запрещено.*/
Person * makePerson(DatabaseID personIdentifier); // функция-фабрика
//для создания объекта Person по уникальному идентификатору из базы данных
DatabaseID askUserForDatabaseID();
// функция для запроса идентификатора у пользователя
DatabaseID id(askUserForDatabaseID());
Person * pp = makePerson(id); // создать объект, поддерживающий интерфейс IPerson
... // манипулировать *pp при помощи методов IPerson
Delete pp; // удаляем объект, когда он больше не нужен
№8 слайд
![Предположим, что старый,](/documents_6/f77a24940abb0149e0193c24303cadd8/img7.jpg)
Содержание слайда: Предположим, что старый, ориентированный только на базы данных класс PersonInfo предоставляет почти все необходимое для реализации конкретных классов – наследников IPerson:
class PersonInfo {
public:
explicit PersonInfo(DatabaseID pid)
virtual ~PersonInfo();
virtual const char *theName() const;
virtual const char *theBirthDate() const;
...
private:
virtual const char *valeDelimOpen() const;
virtual const char *valeDelimClose() const;
// позволяет производным классам задать
// открывающие и закрывающие разделители
...
};
По умолчанию открывающим и закрывающим разделителями служат квадратные скобки, поэтому значение поля «Homer» будет отформатировано так: [Homer]
№9 слайд
![const char PersonInfo](/documents_6/f77a24940abb0149e0193c24303cadd8/img8.jpg)
Содержание слайда: const char *PersonInfo::valueDelimOpen() const{
return “[“; // открывающий разделитель по умолчанию
}
const char *PersonInfo::valueDelimClose() const{
return “]“; // закрывающий разделитель по умолчанию
}
const char * PersonInfo::theName() const
{
// резервирование буфера для возвращаемого значения; поскольку он
// статический, автоматически инициализируется нулями
static char value[Max_Formatted_Field_Value_Length];
// скопировать открывающий разделитель
std::strcpy(value, valueDelimOpen());
// добавить к строке value значение из поля name объекта
//(будьте осторожны – избегайте переполнения буфера!)
std::strcpy(value, valueDelimClose()); // скопировать закрывающий разделитель
return value;
}
PersonInfo упрощает реализацию некоторых функций CPerson.
Стало быть, речь идет об отношении «реализован посредством».
№10 слайд
![class CPerson public IPerson,](/documents_6/f77a24940abb0149e0193c24303cadd8/img9.jpg)
Содержание слайда: class CPerson: public IPerson, private PersonInfo {
// используется множественное наследование
// реализации функций-членов из интерфейса IPerson
public:
explicit CPerson(DatabaseID pid): PersonInfo(pid){}
virtual std::string name() const
{ return PersonInfo::theName();}
virtual std::string birthDate() const
{ return PersonInfo::theBirthDate();}
private:
// переопределения унаследованных виртуальных
// функций, возвращающих строки-разделители
const char * valeDelimOpen() const { return “”;}
const char * valeDelimClose() const { return “”;}
};
№11 слайд
![Множественное наследование](/documents_6/f77a24940abb0149e0193c24303cadd8/img10.jpg)
Содержание слайда: • Множественное наследование сложнее одиночного. Оно может привести к неоднозначности и необходимости применять виртуальное наследование.
• Цена виртуального наследования – дополнительные затраты памяти, снижение быстродействия и усложнение операций инициализации и присваивания. На практике его разумно применять, когда виртуальные базовые классы не содержат данных.
• Множественное наследование вполне законно. Один из сценариев включает комбинацию открытого наследования интерфейсного класса и закрытого наследования класса, помогающего в реализации.
№12 слайд
![class CartoonCharacter](/documents_6/f77a24940abb0149e0193c24303cadd8/img11.jpg)
Содержание слайда: class CartoonCharacter { // персонаж мультфильма
public:
virtual void dance() {} // по умолчанию – ничего не делать
virtual void sing() {}
};
class Grasshopper: public CartoonCharacter {{ //кузнечик
public:
virtual void dance () ; // Определение в другом месте,
virtual void sing() ; // Определение в другом месте.
};
class Cricket: public CartoonCharacter //сверчок
public:
virtual void dance () ;
virtual void sing() ;
};
№13 слайд
![Множественное наследование?](/documents_6/f77a24940abb0149e0193c24303cadd8/img12.jpg)
Содержание слайда: Множественное наследование?
class Cricket : public CartoonCharacter,
private Grasshopper {
public:
virtual void dance() ;
virtual void sin() ;
};
class Grasshopper: public CartoonCharacter {
public:
virtual void dance() ;
virtual void sing();
protected:
virtual void danceCustomizationl();
virtual void danceCustomization2();
virtual void singCustomization() ;
};
№14 слайд
![class Insect public](/documents_6/f77a24940abb0149e0193c24303cadd8/img13.jpg)
Содержание слайда: class Insect: public CartoonCharacter {
public: // Общий код для кузнечиков
virtual void dance () ; //и сверчков
virtual void sing();
protected:
virtual void danceCustomization1 () = 0;
virtual void danceCustomization2 () = 0;
virtual void singCustomization() = 0;
};
class Grasshopper: public Insect {
protected:
virtual void danceCustomization1();
virtual void danceCustomization2();
virtual void singCustomization() ;
};
class Cricket: public Insect {
protected:
virtual void danceCustomization1()
virtual void danceCustomization2();
virtual void singCustomization();
} ;
№15 слайд
![Обращение к именам в](/documents_6/f77a24940abb0149e0193c24303cadd8/img14.jpg)
Содержание слайда: Обращение к именам в шаблонных базовых классах
class CompanyA{
public:
void sendClearText(const std::string& msg);
void sendEncryptedText(const std::string& msg);
...
};
class CompanyB{
public:
void sendClearText(const std::string& msg);
void sendEncryptedText(const std::string& msg);
...
};
... // классы для других компаний
class MsgInfo {...}; // класс, содержащий информацию,
// используемую для создания сообщения
№16 слайд
![template lt typename Company](/documents_6/f77a24940abb0149e0193c24303cadd8/img15.jpg)
Содержание слайда: template<typename Company>
class MsgSender{
public: ... // конструктор, деструктор и т. п.
void sendClear(const MsgInfo& info){
std::string msg;
создать msg из info
Company c;
c.sendClearText(msg);
}
void sendSecret(const MsgInfo& info) {...}
// аналогично sendClear, но вызывает c.sendEncrypted
};
template <typename Company>
class LoggingMsgSender: public MsgSender<Company> {
public: ...
void sendClearMsg(const MsgInfo& info){
записать в протокол перед отправкой;
sendClear(info); // вызвать функцию из базового класса
// этот код не будет компилироваться!
записать в протокол после отправки;
}
...
};
№17 слайд
![class CompanyZ этот класс не](/documents_6/f77a24940abb0149e0193c24303cadd8/img16.jpg)
Содержание слайда: class CompanyZ { // этот класс не представляет функции sendCleartext
public: …
void sendEncrypted(const std::string& msg);
};
Общий шаблон MsgSender не подходит для CompanyZ, потому что в нем определена функция sendClear, которая для объектов класса CompanyZ не имеет смысла. Чтобы решить эту проблему, мы можем создать специализированную версию MsgSender для CompanyZ:
template <> // полная специализация MsgSender
class MsgSender <CompanyZ> {
//отличается от общего шаблона только отсутствием функции sendCleartext
public: …
void sendSecret(const MsgInfo& info){...}
};
template <typename Company>
class LoggingMsgSender: public MsgSender<Company> {
public: ...
void sendClearMsg(const MsgInfo& info){
записать в протокол перед отправкой;
sendClear(info); // если Company == CompanyZ, то этой функции не существует
записать в протокол после отправки;
}
};
№18 слайд
![Варианты решения . Можно](/documents_6/f77a24940abb0149e0193c24303cadd8/img17.jpg)
Содержание слайда: Варианты решения
1. Можно предварить обращения к функциям из базового класса указателем this:
template <typename Company>
class LoggingMsgSender: public MsgSender<Company> {
public:
...
void sendClearMsg(const MsgInfo& info){
записать в протокол перед отправкой;
this->sendClear(info); // порядок! Предполагается, что
// sendClear будет унаследована
записать в протокол после отправки;
}
};
№19 слайд
![. Можно воспользоваться](/documents_6/f77a24940abb0149e0193c24303cadd8/img18.jpg)
Содержание слайда: 2. Можно воспользоваться using-объявлением (делает скрытые имена из базового класса видимыми в производном классе).
template <typename Company>
class LoggingMsgSender: public MsgSender<Company> {
public:
using MsgSender<Company>::sendClear;
// сообщает компилятору о том, что
// sendClear есть в базовом классе
void sendClearMsg(const MsgInfo& info){
...
sendClear(info); // нормально, предполагается, что
... // sendClear будет унаследована
}
};
№20 слайд
![. Явно указать, что](/documents_6/f77a24940abb0149e0193c24303cadd8/img19.jpg)
Содержание слайда: 3. Явно указать, что вызываемая функция находится в базовом классе (недостаток: если вызываемая функция виртуальна, то явная квалификация отключает динамическое связывание).
template <typename Company>
class LoggingMsgSender: public MsgSender<Company> {
pubilc:
void sendClearMsg(const MsgInfo& info){
...
MsgSender<Company>::sendClear(info);
// нормально, предполагается, что
... // sendClear будет унаследована
}
...
};
№21 слайд
![С точки зрения видимости](/documents_6/f77a24940abb0149e0193c24303cadd8/img20.jpg)
Содержание слайда: С точки зрения видимости имен, все три подхода эквивалентны: они обещают компилятору, что любая специализация шаблона базового класса будет поддерживать интерфейс, предоставленный общим шаблоном.
Но если данное обещание не будет выполнено, истина всплывет позже.
LoggingMsgSender<CompanyZ> zMsgSender;
MsgInfo msgData;
... // поместить info в msgData
zMsgSender.sendClearMsg(msgData); // ошибка! не скомпилируется
№22 слайд
![Разбухание кода в результате](/documents_6/f77a24940abb0149e0193c24303cadd8/img21.jpg)
Содержание слайда: Разбухание кода в результате применения шаблонов
template<typename T, std::size_t n> // шаблон матрицы размерностью n x n,
class SquareMatrix { // состоящей из объектов типа T;
public:
...
void invert(); // обращение матрицы на месте
};
В результате конкретизации шаблона может возникнуть дублирование:
SquareMatrix<double, 5> sm1;
...
sm1.invert(); // вызов SquareMatrix<double, 5>::invert()
SquareMatrix<double, 10> sm2;
...
sm2.invert(); // вызов SquareMatrix<double, 10>::invert()
№23 слайд
![template lt typename T gt](/documents_6/f77a24940abb0149e0193c24303cadd8/img22.jpg)
Содержание слайда: template<typename T> // базовый класс, не зависящий
class SquareMatrixBase { // от размерности матрицы
protected:
void invert(std::size_t matrixSize);
// обратить матрицу заданной размерности
...
};
template<typename T, std::size_t n>
class SquareMatrix: private SquareMatrixBase<T> {
private:
using SquareMatrixBase<T>::invert;
// чтобы избежать сокрытия базовой версии invert;
public:
...
void invert() {this->invert(n);} // встроенный вызов параметризованной // версии invert из базового класса
};
№24 слайд
![template lt typename T gt](/documents_6/f77a24940abb0149e0193c24303cadd8/img23.jpg)
Содержание слайда: template<typename T>
class SquareMatrixBase {
protected: ...
SquareMatrixBase(std::size_t n, T pMem) :size(n), pData(pMem){}
// и указатель на данные матрицы сохраняет размерность
void setData(T *ptr) {pData = ptr;} // присвоить значение pData
private:
std::size_t size; // размерность матрицы
T *pData; // указатель на данные матрицы
}; Это позволяет производным классам решать, как выделять память.
template<typename T, size_t size>
class SquareMatrix: private SquareMatrixBase {
public: ...
SquareMatrix() : SquareMatrixBase<t>(n, data) {}
// передать базовому классу размерность матрицы и указатель на данные
private:
T data(n*n); например, прямо в объекте SquareMatrix
};
№25 слайд
![Шаблоны генерируют множество](/documents_6/f77a24940abb0149e0193c24303cadd8/img24.jpg)
Содержание слайда: • Шаблоны генерируют множество классов и функций, поэтому любой встречающийся в шаблоне код, который не зависит от параметров шаблона, приводит к разбуханию кода.
• Разбухания из-за параметров шаблонов, не являющихся типами, часто можно избежать, заменив параметры шаблонов параметрами функций или данными-членами класса.
• Разбухание из-за параметров-типов можно ограничить, обеспечив общие реализации для случаев, когда шаблон конкретизируется типами с одинаковым двоичным представлением
(например, указательные типы list<int*>,
list<const int*>, list<SquareMatrix<long,3>*> и т.п. )
Скачать все slide презентации ООП 8. Варианты наследования одним архивом:
Похожие презентации
-
ООП. Наследование и полиморфизм. Тема 05
-
ООП 7. Наследование и шаблоны
-
Оператор варианта. (Тема 8)
-
Оператор варианта
-
Язык UML. Диаграммы деятельности. Варианты использования
-
ООП Java. Продолжение
-
Объектноориентированное программирование. Наследование
-
Варианты использования. Диаграммы прецедентов. Практическое освоение методологии моделирования
-
Основные понятия ООП
-
Объектно-ориентированное программирование (ООП), как технология программирования