
- •Введение в понятие класса
- •Void queue::init(void)
- •Перегруженные функции
- •Int sqr_it(int I); // Прототипы
- •Перегрузка операций.
- •Наследование
- •Конструкторы и деструкторы
- •Int sloc,rloc;
- •Void qput(int); // Прототип
- •Int qget(void); // Прототип
- •Конструктор с параметрами
- •Конструктор копирования
- •Void input();
- •Void output();
- •Void ThreeAngle::input()
- •Void ThreeAngle::output()
- •Void main(void)
- •Дружественные функции
- •Замечание
- •Дружественные классы
- •Аргументы функций, задаваемые по умолчанию
- •Void main(void)
- •Void stringxy(char *str, int X, int y)
- •Структуры и классы
- •Объединения и классы
- •Void main()
- •Наследование классов
- •Конструкторы с параметрами при наследовании
- •Множественное наследование
- •Перегрузка функций и операций
- •Ключевое слово this
- •Перегрузка операций ввода/вывода. Инсерторы и экстракторы
- •Void main(void)
- •Vector a(1,2,3),b(4,5,6);
- •Void main(void)
- •Vector a(1,2,3),b(4,5,6);
- •Void main(void)
- •Vector a(1,2,3);
- •Дружественные функции-операции
- •Void main(void)
- •Void swap1(int *I, int *j)
- •Void swap(int a, int b)
- •Void swap1(int *I, int *j)
- •Void swap2(int &a, int &b)
- •Использование ссылочных переменных для перегрузки унарных операций
- •Перегрузка операции индексации [ ]
- •Использование виртуальных функций
- •Указатели на производные типы
- •Виртуальные функции
- •Замечания к использованию виртуальных функций
- •Пример использования виртуальных функций
- •Чистые виртуальные функции и абстрактные типы
- •Производные классы и их конструкторы и деструкторы
- •Void main()
- •Конструкторы и деструкторы при множественном наследовании
- •Void main()
- •Виртуальные базовые классы.
- •Операции динамического выделения памяти new и delete
- •Void main(void)
- •Void main(void)
- •Виртуальные деструкторы
- •Void main(void)
- •Void main(void)
- •Шаблоны классов и функций
- •Шаблоны функций
- •Void main(void)
- •Void main(void)
- •Шаблоны классов
- •Int sloc, rloc;
- •Void qput(t I);
- •Void main(void)
- •Статические члены класса
- •Локальные классы
- •Void f(void);
- •Void main(void)
- •Void f(void)
- •Вложенные классы
- •Void main(void)
Использование виртуальных функций
В С++ полиморфизм поддерживается и во время компиляции и во время выполнение программы. Перегрузка функций и операций – это пример полиморфизма во время компиляции. Поддержка полиморфизма во время выполнения программы достигается использованием указателей на базовые классы и виртуальные функции.
Указатели на производные типы
Указатели на базовый тип и на производный тип зависимы. Пусть имеем базовый тип B_class и производный от B_class тип D_class. В С++ всякий указатель, объявленный как указатель на B_class, может быть также указателем на D_class.
B_class *p; // указатель на объект типа B_class
B_class B_obj; // объект типа B_class
D_class D_ob; // объект типа D_class
После этого можно использовать следующие операции:
p=&B_ob; // указатель на объект типа B_class
p=&D_ob; // указатель на объект типа D_class
Все элементы класса D_class, наследуемые от класса B_class, могут быть доступны через использование указателя p. Однако на элементы, объявленные в D_class, нельзя ссылаться, используя p. Если требуется иметь доступ к элементам, объявленным в производном классе, используя указатель на базовый класс, надо привести его к указателю на производный тип. Например, это можно сделать так:
((D_class *)p)->f();
Здесь функция f() – член класса D_class. Внешние круглые скобки необходимы. Хотя указатель на базовый класс может быть использован как указатель на производный класс, обратное, неверно: нельзя использовать указатель на производный класс для присваивания ему адреса объекта базового класса. Кроме того, указатель увеличивается или уменьшается при операциях ++ и – относительно его базового типа.
Пример использования указателей на базовый класс. При этом каждый класс будет содержать функцию void show(void), свою в каждом классе.
#include <iostream.h>
class Base {
public:
void show(void)
{ cout<<”В базовом классе Base\n”; }
};
class Derive: public Base {
public:
void show(void)
{ cout<<”В производном классе Derive\n”; }
};
class Derive1: public Base {
public:
void show(void)
{ cout<<”В производном классе Derive1\n”; }
};
class Derive2: public Base {
public:
void show(void)
{ cout<<” В производном классе Derive2\n”; }
};
void main(void)
{
Base bobj, *pb;
Derive dobj, *pd;
Derive1 d1obj, *pd1;
Derive2 d2obj, *pd2;
pb=&bobj;
bobj.show(); // вызов функции
pb->show(); // show() класса Base
pd=&dobj;
dobj.show(); // вызов функции
pd->show(); // show() класса Derive
pd1=&d1obj;
d1obj.show(); // вызов функции
pd1->show(); // show() класса Derive1
pd2=&d2obj;
d2obj.show(); // вызов функции
pd2->show(); // show() класса Derive2
pb=&dobj; // указателю на базовый класс присвоен адрес производного класса Derive
pb->show(); // вызов show() класса Base!!!!!
pb=&d1obj; // указателю на базовый класс присвоен адрес производного класса Derive1
pb->show(); // вызов show() класса Base!!!!!
((Derive1 *)pb)->show(); // Вызов функции show() класса Derive1
pd1=&d2obj; // указателю на базовый класс Derive1
// присвоен адрес производного класса Derive2
pd1->show(); // вызов функции show() класса Derive1
pd1->Base::show(); // вызов функции show() класса Base!
pd1->Derive::show(); // вызов функции show() класса Derive!
pd1->show(); // вызов функции show() класса Derive1
((Derive2 *)pb)->show(); // Вызов функции show() класса Derive2
}