Перегрузка операций. Перегрузка операции присваивания. Перегрузка операции приведения типа. Перегрузка операции индексирования
Перегрузка операций присваивания.
Операция присваивания должна возвращать ссылку на объект, для которого она вызвана, и принимать в качестве параметра единственный аргумент - ссылку на присваиваемый объект.
const monstr& operator = (const monstr &M)
{if (&m==this) return *this;
if (name != NULL) delete[] name;
{name=new char[strlen(M.name)+1];
strcpy(name, M.name);}
else name=NULL;
health=M.health; ammo=M.ammo;
return *this;}
monstr A(10), B, C; C=B=A;
Перегрузка операции приведения типа.
Фомат операции:
operator имя_типа();
monstr:: operator int() {return health;}
monstr:: operator char*() {return name;}
...
monstr Vasia;
cout<<(int) Vasia<<(char*) Vasia;
Перегрузка операций индексирования.
class Vect
{private:
int *p;
int size;
public:
Vect(int n)
{size=n;
p=new int[size];}
~Vect() {delete[] p;}
... // Методы заполнения массива
...
int & operator[] (int);};
int & Vect:: operator[] (int i)
{if (i<0||i>=size)
{cout<<"неверный индекс";
return p[0];}
return p[i]}
void main()
{Vect a(10);
...
cout<<a[5]<<"\n";
cout<<a[12]<<"\n";} // Сообщение об ошибке.
Наследование. Ключи доступа к элементам базового класса. Простое наследование.
Наследование позволяет строить иерархии, в которых производные классы получают элементы родительских классов и могут дополнять или изменять их свойства
- при описании класса можно перечислять базовые классы
- можно указать, какая видимость требуется для унаследования элементов в порожденном классе с помощью ключей доступа:
1) private – скрытый, частный
2) protected – защищенный
3) public – публичный
ключ доступа | спецификатор в базовом классе | доступ в порожденном классе |
private | private protected public | нет private private |
protected | private protected public | нет protected protected |
public | private protected public | нет protected public |
- конструкторы не наследуются, поэтому производный класс должен иметь свой конструктор
- порядок вызова конструктора:
а) если в производном классе отсутствует явный вызов конструктора базового класса, автоматически вызывается конструктор базового класса по умолчанию
б) после вызова конструктора базового класса выполняется конструктор тех элементов класса, которые являются объектами, и потом выполняется конструктор порожденного класса
в) в случае нескольких базовых классов их конструкторы вызываются в порядке объявления
г) если конструктор базового класса требует указания параметра, он должен быть явно вызван в конструкторе произвольного класса в списке инициализации
- не наследуется операция присваивания, поэтому ее также требуется явно определить в производном классе
- деструктор не наследуется, и если он не описан в производном классе, то он формируется по умолчанию и вызывает деструктор базовых классов. Деструктор вызывается в обратном порядке вызову конструктора.
Виртуальные методы. Механизм позднего связывания.
Указателю на базовый класс можно присвоить значение адреса объекта любого производного класса
monstr *p;
p=new daemon;
virtual void draw(int, int, int, int);
- если в базовом классе метод определен как виртуальный, то метод, определенный в производном классе с тем же именем и набором параметров, автоматически становится виртуальным
- виртуальные методы наследуются
- виртуальный метод не может объявляться с модификатором static
- если вводится описание виртуального метода, он должен быть определен хотя бы как чисто виртуальный (virtual void func(int)=0;)
таблица виртуальных методов класса X(vtbl)
virtual func1()
virtual func2()
virtual func3()
объект класса X
void *vtpr;