Slide 1

Slide 1 text

ОБЪЕКТНО- ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ Лекция № 1 / 03

Slide 2

Slide 2 text

MEMBER INITIALIZER LIST //complex.h class Complex{ double re, im; public: Complex(); Complex(double re, double im); ... }; //complex.cpp Complex::Complex(){ re = 0.; im = 0.; } Complex::Complex(double re, double im){ this->re = re; this->im = im; } copy initialization

Slide 3

Slide 3 text

MEMBER INITIALIZER LIST //complex.h class Complex{ double re, im; public: Complex(); Complex(double re, double im); ... }; //complex.cpp Complex::Complex() : re(0.), im(0.){ } Complex::Complex(double re, double im) : re(re), im(im) { } direct initialization initializer list

Slide 4

Slide 4 text

MEMBER INITIALIZER LIST //complex.h class Complex{ double re, im; public: Complex(); Complex(double re, double im); ... }; //complex.cpp Complex::Complex() : re{ 0. }, im{ 0. }{ } Complex::Complex(double re, double im) : re{ re }, im{ im } { } uniform initialization (since C++11) initializer list

Slide 5

Slide 5 text

DELEGATING CONSTRUCTOR //complex.h class Complex{ double re, im; public: Complex(); Complex(double re, double im); ... }; //complex.cpp Complex::Complex() : Complex(0., 0.){ } Complex::Complex(double re, double im) : re{ re }, im{ im } { } Complex() delegates to Complex(double, double) initializer list

Slide 6

Slide 6 text

MEMBER INITIALIZER LIST //complex.cpp Complex::Complex() : im(0.), re(im) { } re = ???; im = ???;

Slide 7

Slide 7 text

MEMBER INITIALIZER LIST //complex.cpp Complex::Complex() : im(0.), re(im) { } re = -9.25596e+61; im = 0;

Slide 8

Slide 8 text

1. Инициализация виртуальных базовых классов. 2. Инициализация прямых базовых классов. INITIALIZATION ORDER 3. Инициализация нестатических полей в порядке их объявления в классе. 4. Выполнение тела конструктора.

Slide 9

Slide 9 text

REFERENCE //reference declaration Type& nameRef = some_object; const Type& nameRef = some_object; Ссылка - это псевдоним уже существующего объекта (альтернативное имя объекта).

Slide 10

Slide 10 text

REFERENCE int a = 2; int &a_ref = a; int *a_ptr = &a; a_ref = 3; printf("%d\n", a); // 3 2 a: &a a_ptr: a_ref: Ссылку можно воспринимать как константный указатель, который разыменуется (неявно) при использовании.

Slide 11

Slide 11 text

void swap(int p, int q) { int r = p; p = q; q = r; } void swap(int *p, int *q) { int r = *p; *p = *q; *q = r; } void swap(int &p, int &q) { int r = p; p = q; q = r; } REFERENCE Idiot-style C-style C++-style

Slide 12

Slide 12 text

//stack.h class Stack{ size_t size; /*...*/ public: Stack(); ~Stack(); void clear(); void push(int node); void pop(); int& top(); const int& top() const; ... }; REFERENCE

Slide 13

Slide 13 text

int& ref; //error: ссылка должна быть // проинициализирована int& *ref; //error: нельзя создать указатель // на ссылку. int& &ref; //error: нельзя создать ссылку // на ссылку. int& ref = 1; //error: нельзя создать не константную // lvalue-ссылку на временный объект. int a; int* &ref = &a; //ok: ссылка на указатель const int& ref = 1; //ok: константная ссылка // на временный объект. REFERENCE

Slide 14

Slide 14 text

REFERENCE VS POINTER 1. Нельзя иметь пустые (NULL) ссылки. Указатели можно. 2. Нельзя переинициализировать ссылку. Указатели могут указывать на другие объекты. 3. Ссылка обязательно должная быть инициализирована.

Slide 15

Slide 15 text

COMPOSITION class Base{ int baseInt; char baseChar; }; class Composed{ Base base; char composedChar; int composedInt; }; baseInt baseChar padding Base 8 baseInt baseChar padding composedChar padding composedInt Composed 16

Slide 16

Slide 16 text

INHERITANCE class Base{ int baseInt; char baseChar; }; class Composed{ Base base; char composedChar; int composedInt; }; baseInt baseChar padding Base 8 baseInt baseChar padding composedChar padding composedInt Composed 16 class Derived: public Base{ char derivedChar; int derivedInt; }; baseInt baseChar padding derivedChar padding derivedInt Derived MSVC compiler

Slide 17

Slide 17 text

INHERITANCE class Base{ int baseInt; char baseChar; }; class Composed{ Base base; char composedChar; int composedInt; }; baseInt baseChar padding Base 8 baseInt baseChar padding composedChar padding composedInt Composed 12 class Derived: public Base{ char derivedChar; int derivedInt; }; baseInt baseChar derivedChar padding derivedInt Derived Clang compiler

Slide 18

Slide 18 text

INHERITANCE Base Derived Superclass Subclass Shape Circle Rectangle Or

Slide 19

Slide 19 text

INHERITANCE class Base{ int baseInt; char baseChar; public: Base(): baseInt(0), baseChar('0'){ } ... }; class Derived: public Base{ char derivedChar; int derivedInt; public: Derived(char a, int b): derivedChar(a), derivedInt(b){ } ... }; Автоматически вызовется Base()

Slide 20

Slide 20 text

INHERITANCE class Base{ int baseInt; char baseChar; public: Base(): baseInt(0), baseChar('0'){ } ... }; class Derived: public Base{ char derivedChar; int derivedInt; public: Derived(char a, int b): Base(), derivedChar(a), derivedInt(b){ } ... }; Можно и так.

Slide 21

Slide 21 text

INHERITANCE class Base{ int baseInt; char baseChar; public: Base(int baseA, char baseB): baseInt(baseA), baseChar(baseB){ } ... }; class Derived: public Base{ char derivedChar; int derivedInt; public: Derived(int baseA, char baseB, char a, int b) : Base(baseA, baseB), derivedChar(a), derivedInt(b){ } ... }; Обязательно вызывать в явном виде

Slide 22

Slide 22 text

CONSTRUCTION & DESTRUCTION ORDER Construction of 'Derived2' class Base ctor Derived1 ctor Derived2 ctor Base Derived1 Derived2 Diagram classes Destruction of 'Derived2' class Base dtor Derived1 dtor Derived2 dtor

Slide 23

Slide 23 text

USING INHERITANCE int main(){ Derived* derPtr = new Derived; Base* basePtr = derPtr; return 0; }; baseInt baseChar derivedChar derivedInt *derPtr derPtr *derPtr basePtr baseInt baseChar derivedChar derivedInt поля 'Derived' класса не доступны для basePtr

Slide 24

Slide 24 text

USING INHERITANCE int main(){ Derived* derPtr = new Derived; Base& baseRef = *derPtr; return 0; }; baseInt baseChar derivedChar derivedInt *derPtr derPtr *derPtr baseRef baseInt baseChar derivedChar derivedInt поля 'Derived' класса не доступны для baseRef

Slide 25

Slide 25 text

USING INHERITANCE int main(){ Derived* derPtr = new Derived; Base base = *derPtr; return 0; }; baseInt baseChar derivedChar derivedInt *derPtr derPtr base baseInt baseChar It's new object. copying operation

Slide 26

Slide 26 text

USING INHERITANCE int main(){ std::vector shapes; shapes.push_back(new Circle(1, 2, 2)); shapes.push_back(new Rectangle(5, 5, 5, 5)); shapes.push_back(new Square(10, 10, 2)); for(int i = 0; shapes.size() > i; ++i){ shapes[i]->draw(); delete shapes[i]; } return 0; }; virtual function Shape Circle Rectangle Square

Slide 27

Slide 27 text

MULTIPLE INHERITANCE class BaseA{ int fieldA; }; class BaseB{ int fieldB; }; class Derived : public BaseA, public BaseB{ int fieldD; }; BaseA BaseB fieldD Derived BaseA BaseB Derived

Slide 28

Slide 28 text

USING MULTIPLE INHERITANCE int main(){ Derived* derPtr = new Derived; BaseA* baseA = derPtr; BaseB* baseB = derPtr; return 0; }; *derPtr derPtr BaseA BaseB fieldD *derPtr baseA BaseA BaseB fieldD *derPtr baseB BaseA BaseB fieldD

Slide 29

Slide 29 text

USING MULTIPLE INHERITANCE int main(){ Derived* derPtr = new Derived; BaseA& baseA = *derPtr; BaseB& baseB = *derPtr; return 0; }; *derPtr derPtr BaseA BaseB fieldD *derPtr baseA BaseA BaseB fieldD *derPtr baseB BaseA BaseB fieldD

Slide 30

Slide 30 text

USING MULTIPLE INHERITANCE int main(){ Derived* derPtr = new Derived; BaseA baseA = *derPtr; BaseB baseB = *derPtr; return 0; }; *derPtr derPtr BaseA BaseB fieldD baseA BaseA baseB BaseB

Slide 31

Slide 31 text

"DREADED DIAMOND" class BaseA : public UltimateBase{ int fieldA; }; class BaseB : public UltimateBase{ int fieldB; }; class Derived : public BaseA, public BaseB{ int fieldD; }; class UltimateBase{ int fieldU; }; BaseA BaseB Derived UltimateBase

Slide 32

Slide 32 text

"DREADED DIAMOND" class BaseA : public UltimateBase{ int fieldA; }; class BaseB : public UltimateBase{ int fieldB; }; class Derived : public BaseA, public BaseB{ int fieldD; }; class UltimateBase{ int fieldU; }; UltimateBase fieldA UltimateBase fieldB fieldD Derived

Slide 33

Slide 33 text

int main(){ Derived* derPtr = new Derived; UltimateBase* ultimateBase = derPtr; return 0; }; "DREADED DIAMOND" UltimateBase fieldA UltimateBase fieldB fieldD Derived ultimateBase ???

Slide 34

Slide 34 text

int main(){ Derived* derPtr = new Derived; BaseA* baseA = derPtr; UltimateBase* ultimateBase = baseA; delete devPtr; return 0; }; "DREADED DIAMOND" UltimateBase fieldA UltimateBase fieldB fieldD Derived ultimateBase

Slide 35

Slide 35 text

VIRTUAL INHERITANCE

Slide 36

Slide 36 text

class BaseA : virtual public UltimateBase{ int fieldA; }; class BaseB : virtual public UltimateBase{ int fieldB; }; class Derived : public BaseA, public BaseB{ int fieldD; }; class UltimateBase{ int fieldU; }; VIRTUAL INHERITANCE vbptr fieldA padding fieldU BaseA 12 0 12 vbptr - указатель на таблицу адресования виртуальных базовых классов.

Slide 37

Slide 37 text

VIRTUAL INHERITANCE vbptr Смещение от vbptr до начала класса Смещение от vbptr до виртуального базового класса 1 Смещение от vbptr до виртуального базового класса 2 ... Смещение от vbptr до виртуального базового класса N MSVC compiler

Slide 38

Slide 38 text

class BaseA : virtual public UltimateBase{ int fieldA; }; class BaseB : virtual public UltimateBase{ int fieldB; }; class Derived : public BaseA, public BaseB{ int fieldD; }; class UltimateBase{ int fieldU; }; VIRTUAL INHERITANCE vbptr fieldA padding vbptr fieldB padding fieldD fieldU Derived 12 0 28 24 28 0 16

Slide 39

Slide 39 text

int main(){ Derived* derPtr = new Derived; UltimateBase* ultimateBase = derPtr; return 0; }; ultimateBase VIRTUAL INHERITANCE vbptr fieldA padding vbptr fieldB padding fieldD fieldU Derived 0 28

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

VIRTUAL FUNCTIONS class Shape{ int x, y; public: Shape(int x, int y); virtual ~Shape(); virtual double square() const; virtual double perimeter() const; virtual double move(int x, int y); int getX() const; int getY() const; }; vfptr x y Shape class Circle: public Shape{ int radius; public: Circle(int x, int y, int radius); virtual ~Circle(); virtual double square() const; virtual double perimeter() const; }; MSVC compiler &Shape::{dtor} &Shape::square &Shape::perimeter &Shape::move vfptr - указатель на таблицу виртуальных функций. У каждого класса своя таблица виртуальных функций. declaration order

Slide 42

Slide 42 text

VIRTUAL FUNCTIONS class Shape{ int x, y; public: Shape(int x, int y); virtual ~Shape(); virtual double square() const; virtual double perimeter() const; virtual double move(int x, int y); int getX() const; int getY() const; }; vfptr x y radius Circle class Circle: public Shape{ int radius; public: Circle(int x, int y, int radius); virtual ~Circle(); virtual double square() const; virtual double perimeter() const; }; MSVC compiler &Circle::{dtor} &Circle::square &Circle::perimeter &Shape::move

Slide 43

Slide 43 text

int main(){ Circle* circlePtr = new Circle(1, 1, 1); Shape* shapePtr = circlePtr; shapePtr->move(1, 2); shapePtr->square(); delete shapePtr; return 0; }; VIRTUAL FUNCTIONS *circlePtr shapePtr vfptr x y radius &Circle::{dtor} &Circle::square &Circle::perimeter &Shape::move

Slide 44

Slide 44 text

КОНЕЦ ТРЕТЬЕЙ ЛЕКЦИИ virtual ~Lection() { }