Перегрузка операторов - обращение и память
•
Обращение
к
элементу
массива
x[y]:
operator
C:\Users\Admin\AppData\Local\Temp\T y
;
•
Обращение с разыменованием («объект на который указывает x»)
x:
operator
();
•
Взятие адреса &x: operator &();
•
Обращение к члену объекта x->y: operator ->();
•
Обращение к объекту, на который указывает y: x->
y: operator ->
(T x);
77
•
Вызов функции x(a1, a2): operator ()(T a1, U a2, ...);
•
Оператор "запятая" x, y: operator ,(T y);
•
Преобразование типа (type) x: operator T();
•
Выделение памяти new type: void* operator new(size_t x);
•
Выделение памяти (массив) new type[n]: void* operator
new
C:\Users\Admin\AppData\Local\Temp\size_t x
;
•
Освобождение памяти delete x: operator delete(void* x);
•
Освобождение
памяти
(массив)
delete[]
x:
operator
delete
C:\Users\Admin\AppData\Local\Temp\void* x
;
Не перегружаемые операторы
•
Обращение к члену структуры x.y
•
Обращение к объекту, на который указывает y x.*y
•
Условный оператор x ? y : c
•
Оператор области видимости x::y
•
Размер sizeof(x) sizeof(type)
•
Выравнивание alignof(type)
•
Идентификация типа typeid(x)
Наследование (inheritance)
Классы в C++ могут быть расширены с помощью механизма
наследования, позволяющего создавать новые классы на основе имеющихся.
Класс, которому наследуют, называется базовым (base class). Класс, который
наследует - производным (derived class). При наследовании производный класс
наследует поля и методы своего базового класса, как правило, добавляя при
этом новые поля и/или методы. Производный класс, добавляя поля и методы,
является более частным типом, а базовый класс - более общим. Пример:
базовый класс - класс геометрических фигур на плоскости, происзодные классы
-
круг, квадрат, требугольник. В результате построения классификации в
предметной области программы возникает диаграмма классов (class diagramm).
С технической точки зрения объекты производного класса содержат
внутри себя все поля и методы базового. При этом закрытые поля 'private'
базового класса в производном классе недоступны. Наследование может быть
открытым, закрытым и защищенным (public, private, protected). Если тип
наследования не указан, то наследование считается закрытым для класса и
открытым для структуры. При открытом наследовании в производном классе
поля и методы базового класса сохраняют свои спецификаторы доступа. При
закрытом наследовании в производном классе всё становится закрытым. При
защищенном - защищенным.
Тип
наследования
Спецификатор в базовом
классе
Доступ в производном
классе
public
private
недоступен
protected
protected
public
public
potected
private
недоступен
78
protected
protected
public
protected
private
private
недоступен
protected
private
public
private
Наследование может производиться несколько раз, при этом при каждом
наследовании будут выполняться описанные выше правила доступа
// базовый класс
class Example
{
public:
double re, im;
double mod();
};
// производный класс, открытое наследование
class Derived: public Example
{
// новых полей в класс Derived не добавили.
// новый класс будет содержать только поля базового.
};
// еще один производный класс, открытое наследование
class DerivedTwice: public Derived
{
// новых полей в класс Derived не добавили.
// новый класс будет содержать только поля базового.
};
...
// Определение объектов этих классов
Example x;
Derived y;
DerivedTwice z;
...
// доступ к полям и методам
x.re = y.re = z.re = 1.0;
x.im = y.im = z.im = 1.0;
cout << x.mod();
cout << y.mod();
cout << z.mod();
Наконец, наследование может быть множественным, в котором случае
производный класс наследует поля и методы двух или более классов.
// базовый класс
class Sample
79
{
public:
bool validity;
};
// производный класс, открытое наследование
class Derived: public Example, public Sample
{
// Доступ к полям базовых классов по имени или в случае конфликата имен
//
используя селектор Example::mod(), Sample::validity
};
...
// Определение объектов этих классов
Derived x;
...
// доступ к полям и методам
x.validity = true;
cout << x.mod();
Виртуальное наследование (virtual inheritance) и то, зачем оно
необходимоо здесь подробно рассматривать не будем. За разъяснениями можно
обратиться сюда: http://ru.wikipedia.org/wiki/Виртуальное_наследование
Его смысл в том, что при множественном наследовании от классов,
имеющих общий базовый класс, общий предок передается потомку в
единственном экземпляре, а не множественном, от каждого из родителей.
class B { };
class X : public virtual B { };
class Y : public virtual B { };
class XY : public X, public Y { };
XY xy;
// объект 'xy' содержит только один экземпляр полей класса 'B'.
Конструкторы, операторы копирования, перемещения и деструкторы не
наследуются. Но их реализацией в базовом классе можно воспользоваться с
помощью ключевого слова 'using'.
class Derived: public Example
{
public:
using Example::Example();
// использование конструктора базового
//
класса в производном
Derived(int i);
// новый конструктор
}
Объявление в производном классе полей и методов с тем же исменем, что и в
базовом, скроет имена базового класса от пользователя.
При создании объекта производного класса соблюдается строгий порядок
инициализации. Сначала вызываются конструкторы базовых классов в порядке
80
их перечисления в списке наследования. Затем вызываются конструкторы
полей класса в порядке их объявления в объявлении класса. После того как
будут сконструированы все базовые классы и поля, выполняется тело
конструктора.
Конструкторы копий базовых классов вызываются в том порядке, в
котором они объявлены в списке наследования. Конструкторы копий полей
класса вызываются в том порядке, в котором они объявлены в объявлении
класса.
Деструкторы всегда вызываются в порядке, обратном порядку вызова
конструкторов.
Do'stlaringiz bilan baham: |