Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
О.О.П / ооп / 18. Об'єктно-орієнтоване програмування, л.5.5 - 5.8.ppt
Скачиваний:
26
Добавлен:
30.05.2020
Размер:
3.38 Mб
Скачать

class CTable

{

public:

CTable(std::string const& dbFileName)

{

m_tableFile.Open(dbFileName); std::cout << "Table

constructed\n";

}

virtual ~CTable()

{

m_tableFile.Close();

std::cout << "Table destroyed\n";

}

private:

CFile m_tableFile; };

Output:

Table constructed

Indexed table created

Indexed table destroyed

Table destroyed

class CIndexedTable : public CTable

{

public:

CIndexedTable(std::string const& dbFileName,

std::string const& indexFileName)

:CTable(dbFileName)

{

m_indexFile.Open(indexFileName); std::cout << "Indexed table created\n";

}

~CIndexedTable()

{

m_indexFile.Close();

std::cout << "Indexed table destroyed\n";

}

private:

CFile m_indexFile; };

int main(int argc, char * argv[])

{

CIndexedTable table("users.dat", "users.idx");

return 0;

}

Перевантаження

методів

вУкласіC++ метод спадкоємцевіпохідного класу заміщає собою всі методи батьківського класу з тим же

ім'ям

Кількість і типи аргументів значення не мають

Для виклику методу батьківського класу з методу класу спадкоємця використовується метод Base::

class CBase

int main(int argc, char * argv[])

{

 

 

 

 

 

{

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

CDerived derived;

public:

 

 

 

 

 

 

 

 

 

void Print()

 

 

// вызов метода Print()

наследника

{

 

 

 

 

 

 

 

 

 

 

 

 

 

 

derived.Print("test");

 

 

}

 

std::cout << "CBase::Print\n";

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

std::cout << "===\n";

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

void Print(std::string const& param)

 

 

// вызов метода Print() базового класса

{

 

 

 

 

 

 

 

 

 

 

 

 

 

 

derived.CBase::Print();

 

 

 

}

 

std::cout << "CBase::Print " << param << "\n";

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

std::cout << "===\n“;

 

 

 

 

};

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

// вызов метода Print базового класса

class CDerived : public CBase

 

 

 

 

derived.CBase::Print("test1");

 

{

 

 

 

 

 

 

 

 

public:

 

 

return 0;

void Print(std::string const& param)

 

 

}

 

 

 

 

 

{

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

CBase::Print(param);

 

 

 

 

 

 

 

 

 

 

 

 

Output:

 

 

std::cout << "CDerived::Print " << param << "\n";

 

 

 

 

 

 

CBase::Print test

 

 

 

 

 

 

 

 

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

CDerived::Print test

};

 

 

 

 

 

 

 

 

 

 

 

 

 

 

===

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

CBase::Print

 

 

 

 

 

 

 

 

===

 

 

 

 

 

 

 

 

 

 

 

 

CBase::Print test1

 

 

 

 

 

 

 

 

 

 

 

 

 

Завдання - ієрархія геометричних фігур

Розглянемо наступну ієрархію геометричних фігур:

CShape – базовий клас «фігура»

CCircle – клас, що моделює коло

CRectangle - клас, що моделює прямокутник

Кожна фігура володіє наступними властивостями:

Ім'я : «Shape», «Circle» або «Rectangle»Площа фігури

class CShape

{

public:

std::string GetType()const{return "Shape";} double GetArea()const{return 0;}

};

class CRectangle : public CShape

{

public:

CRectangle(double width, double height) :m_width(width), m_height(height){}

std::string GetType()const{return "Rectangle";} double GetArea()const{ return m_width * m_height; }

private:

double m_width; double m_height;

};

class CCircle : public CShape

{

public:

CCircle(double radius):m_radius(radius){} std::string GetType()const{return "Circle";}

double GetArea()const{return 3.14159265 * m_radius * m_radius;} private:

double m_radius;

};

int main(int argc, char * argv[])

{

CCircle circle(10); CRectangle rectangle(20, 10);

std::cout << "Circle area: " << circle.GetArea() << "\n";

std::cout << "Rectangle area: " << rectangle.GetArea() << "\n";

return 0;

}

Output:

Circle area: 314.159

Rectangle area: 200

void PrintShapeArea(CShape const& shape)

{

std::cout << shape.GetType() << " area: " << shape.GetArea() << "\n";

}

int main(int argc, char * argv[])

{

CCircle circle(10);

CRectangle rectangle(20, 10);

PrintShapeArea(circle);

PrintShapeArea(rectangle);

return 0;

}

Output:

Shape area: 0

Shape area: 0

У чому ж проблема?

Проблема в тому, що в даній ситуації при виборі методів, що викликаються, компілятор керується типом послання або покажчика

У нашому випадку відбувається виклик методів класу CShape, оскільки функція PrintShapeArea приймає посилання даного типа

Методи, при виклику яких необхідно керуватися типом об'єкту, мають бути оголошені віртуальними