Виртуальные базовые классы

Содержание

Слайд 2

Постановка проблемы Бывает, что класс оказывается потомком различных базовых классов, имеющих

Постановка проблемы

Бывает, что класс оказывается потомком различных базовых классов, имеющих общего

предка
Окно Bottom_Window при изменении размера отображает последние строки
Окно Shell_Window было рассмотрено раньше
Как сделать окно Bottom_Shell_Window ?
Слайд 3

Схема наследования

Схема наследования

Слайд 4

Класс Bottom_Window class Bottom_Window : public Window { public: Bottom_Window( const

Класс Bottom_Window

class Bottom_Window : public Window {
public:
Bottom_Window( const Point&

upper_left ,
const Point& size , const String& utitle );
void change_size( const Point& new_size );
};
Слайд 5

Метод change_size() класса Bottom_Window void Bottom_Window :: change_size ( const Point&

Метод change_size() класса Bottom_Window
void Bottom_Window :: change_size ( const Point& new_size )
{
int

shrinkage = size( ).y( ) - new_size.y( ) ;
for( int i = 0 ; i < shrinage ; i++ ) scroll_up( );
Window::change_size ( new_size );
}
Слайд 6

Класс Bottom_Shell_Window class Bottom_Shell_Window : public Sell_Window, public Bottom_Window { public:

Класс Bottom_Shell_Window

class Bottom_Shell_Window : public Sell_Window, public Bottom_Window
{
public:
Bottom_Shell_Window( const

Point& upleft,
const Point& size, const String& title);
void change_size(const Point& new_size);
};
Слайд 7

Объект класса Bottom_Shell_Window

Объект класса Bottom_Shell_Window

Слайд 8

Объект класса Bottom_Shell_Window

Объект класса Bottom_Shell_Window

Слайд 9

Классы Shell_Window и Bottom_Window class Shell_Window : virtual public Window {

Классы Shell_Window и Bottom_Window

class Shell_Window : virtual public Window {
// …………..
};
class

Bottom_Window : virtual public Window {
// …………..
};
Слайд 10

Метод change_size() класса Bottom_Shell_Window void Bottom_Shell_Window :: change_size(const Point& size )

Метод change_size() класса Bottom_Shell_Window
void Bottom_Shell_Window :: change_size(const Point& size )
{
Bottom_Window::change_size ( size

) ;
Shell_Window::change_size ( size );
}
Слайд 11

Дублирование вызова метода

Дублирование вызова метода

Слайд 12

Решение проблемы

Решение проблемы

Слайд 13

Класс Bottom_Window class Bottom_Window : virtual public Window { public: Bottom_Window(

Класс Bottom_Window

class Bottom_Window : virtual public Window {
public:
Bottom_Window( const Point&

upleft,
const Point& size, const String& title);
void change_size(const Point& new_size);
protected:
void befor_change_size(const Point& new_size);
void after_change_size(const Point& new_size);
};
Слайд 14

Методы класса Bottom_Window void Bottom_Window::befor_change_size(const Point& nsz) { int shrinkage =

Методы класса Bottom_Window

void Bottom_Window::befor_change_size(const Point& nsz) {
int shrinkage = size(

).y( ) - nsz.y( ) ;
for( int i = 0 ; i < shrinage ; i++ ) scroll_up( );
}
void Bottom_Window::after_change_size(const Point& ) {
// не нужно ничего делать после изменения размера
}
void Bottom_Window::change_size(const Point& new_size) {
befor_change_size( new_size ) ;
Window::change_size( new_size ) ;
after_change_size( new_size );
};
Слайд 15

Класс Shell_Window class Shell_Window : virtual public Window { public: Shell_Window(

Класс Shell_Window

class Shell_Window : virtual public Window {
public:
Shell_Window( const Point&

upleft,
const Point& size, const String& title);
int execute ( const String& command );
void change_size(const Point& new_size);
protected:
Point valid_new_size(const Point& new_size);
};
Слайд 16

Методы класса Bottom_Window const Point min_SW_size (40,3); Point Shell_Window::valid_new_size(const Point& new_size)

Методы класса Bottom_Window

const Point min_SW_size (40,3);
Point Shell_Window::valid_new_size(const Point& new_size)
{
return max(

new_size, min_SW_size);
}
void Shell_Window::change_size(const Point& new_size) {
Window::change_size( valid_new_size(new_size) ) ;
};
Слайд 17

Метод change_size() класса Bottom_Shell_Window void Bottom_Shell_Window :: change_size(const Point& size )

Метод change_size() класса Bottom_Shell_Window
void Bottom_Shell_Window :: change_size(const Point& size )
{
Point new_size =

Shell_Window::valid_new_size ( size );
Bottom_Window::befor_change_size ( new_size ) ;
Window::change_size ( new_size );
Bottom_Window::after_change_size ( new_size ) ;
}
Слайд 18

Проблема конструктора Если у класса не виртуальный предок, то при конструировании

Проблема конструктора

Если у класса не виртуальный предок, то при конструировании объекта

класса однозначно вызывается конструктор предка (статическое связывание)
Класс, производный от такого базового класса не знает о «дедушке», и его конструктор должен передать параметры только конструктору класса- «папы»
При множественном наследовании, если «родители» класса имеют общего не виртуального предка, то для объекта-«внука» будет дважды вызываться конструктор «деда»
Слайд 19

Не виртуальное наследование class Shell_Window : public Window { // …………..

Не виртуальное наследование

class Shell_Window : public Window {
// …………..
};
class Bottom_Window :

public Window {
// …………..
};
class Bottom_Shell_Window : public Shell_Window ,
public Bottom_Window {
// …………..
};
Слайд 20

Дублирование вызова конструктора Конструктор класса Window

Дублирование вызова конструктора

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

Слайд 21

Решение проблемы конструктора Если у класса виртуальный предок, то для его

Решение проблемы конструктора

Если у класса виртуальный предок, то для его классов-«детей»

конструирование объекта зависит от происхождения остальных «родителей» (динамическое связывание)
При множественном наследовании, если «родители» класса имеют общего виртуального предка, то для объекта-«внука» дважды вызываться конструктор «деда» не будет
Это значит, что класс, производный от таких классов-«родителей» должен знать о «дедушке», и его конструктор должен передать параметры не только конструкторам классов-«родителей», но и конструктору класса-«деда»
Слайд 22

Виртуальное наследование class Shell_Window : virtual public Window { // …………..

Виртуальное наследование

class Shell_Window : virtual public Window {
// …………..
};
class Bottom_Window :

virtual public Window {
// …………..
};
class Bottom_Shell_Window : public Shell_Window ,
public Bottom_Window {
// …………..
};
Слайд 23

Конструктор класса Shell_Window Управление конструкторами предков Конструктор класса Window Конструктор класса Bottom_Window

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

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

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

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

Слайд 24

Конструкторы классов Bottom_Window и Shell_Window Bottom_Window:: Bottom_Window (const Point& up_left, const

Конструкторы классов Bottom_Window и Shell_Window

Bottom_Window:: Bottom_Window (const Point& up_left, const Point&

size, const String& title) : Window (up_left, size, title)
{ }
Shell_Window:: Shell_Window (const Point& up_left, const Point& size, const String& title) : Window (up_left, valid_new_size(size), “|”+title+“|”)
{ }
Слайд 25

Конструктор класса Bottom_Shell_Window Bottom_Shell_Window:: Bottom_Shell_Window ( const Point& up_left, const Point&

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

Bottom_Shell_Window:: Bottom_Shell_Window (
const Point& up_left, const Point& size,const

String& title) :
Window(up_left, Sell_Window::valid_new_size(size),“|”+title+“|”),
Shell_Window(up_left, Sell_Window::valid_new_size(size), “|”+title+“|”) ,
Bottom_Window(up_left, Sell_Window::valid_new_size(size), “|”+title+“|”) ,
{ }
Слайд 26

Создание объекта класса Bottom_Shell_Window Выделяется память Конструктор класса Bottom_Shell_Window вычисляет аргументы

Создание объекта класса Bottom_Shell_Window

Выделяется память
Конструктор класса Bottom_Shell_Window вычисляет аргументы для

конструктора класса Window
Выполняется тело конструктора класса Window
Конструктор класса Bottom_Shell_Window вычисляет аргументы для конструкторов класса Bottom_Window и Shell_Window
Конструкторы классов Bottom_Window и Shell_Window НЕ вычисляет аргументы для конструктора класса Window
Выполняются тела конструкторов классов Bottom_Window и Shell_Window
Выполняется тело конструктора класса Bottom_Shell_Window