Int main() {
X x;
X *px = &x; // Указатель на базовый класс
Y y;
x.seti(10);
y.seti(15);
px->print(); // класс X: 10
px = &y;
px->print(); // класс Y: 15
cin.get();
return 0;
}
19. Абстрактный базовый класс, определение, назначение, пример.
Абстрактный базовый класс – это класс, который содержит только чисто виртуальные методы.
Чистые виртуальные функции - это функции, которые не имеют определения.
Деструктор АБК обязательно должен быть виртуальным.
Цель подобных функций – просто определить функционал без реализации, а реализацию определят производные классы. Чтобы определить виртуальную функцию как чистую, её объявление завершается значением "=0".
Объявление чисто виртуальной функции: virtual void print() const = 0; (const после функции, перед “=0” означает, что функция не изменяет поля объекта.
Чисто виртуальная функция может выглядеть и так virtual void print() = 0;)
(тут АБК представляет класс для расчёта площадей различных фигур, которые
являются его наследниками)
#include <math.h>
#include <iostream>
using namespace std;
class fig //АБК для всех фигур {
public: virtual double ploshad() const = 0;
virtual ~fig() {}
};
class krug: public fig // класс круга {
double x;
public:
krug(double y=0) : x(y) {}
virtual double ploshad() const {
return 3.14 * x * x;
}
};
class pruamoug : public fig // класс прямоугольника {
double x,y;
public:
pruamoug(double a=0, double b=0) : x(a), y(b) {}
virtual double ploshad() const {
return x*y;
}
};
int main(void) {
fig* a[2]; krug k(2); pruamoug p(2, 3); double sr=0;
a[0] = &k; // определяем массив указателей на базовый класс через
адреса наследников
a[1] = &p;
for (int i = 0; i < 2;i++) // для вычисления площади будет вызываться
метод соответствующей фигуры т.к. в базовом классе он виртуальный {
sr += a[i]->ploshad();
}
cout << "summa=" << sr; // summa=18.56
return 0;
}
20. Наследование. Виртуальные деструкторы, их назначение, пример.
Однако на самом деле мы хотим, чтобы функция удаления вызывала деструктор Derived (который, в свою очередь, вызывает деструктор Base), иначе m_array не будет удален. Мы можем сделать это, сделав деструктор Base виртуальным:
#include <iostream>
class Base{
public:
virtual ~Base() // обратите внимание: виртуальный{
std::cout << "Calling ~Base()\n";
}
};
class Derived: public Base{
private:
int* m_array;
public:
Derived(int length)
: m_array{ new int[length] }{
}
virtual ~Derived() // обратите внимание: виртуальный{
std::cout << "Calling ~Derived()\n";
delete[] m_array;
}
};