Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
шпоры по ООП.doc
Скачиваний:
31
Добавлен:
25.09.2019
Размер:
1.04 Mб
Скачать

30.Объекты класса и указатели на объекты класса.

#include <iostream.h>

class A

{

};

class AB: public A

{

};

class AC: public A

{

};

void main ()

{

A *pObj;

A MyA;

pObj = &MyA;

cout << "OK A" << endl;

AB MyAB;

AC MyAC;

pObj = &MyAB;

cout << "OK AB" << endl;

pObj = &MyAC;

cout << "OK AC" << endl;

}

Это очень простой пример. Пустые классы, простое наследование… Единственно, что важно в объявлении этих классов - спецификаторы доступа в описании баз производных классов. Базовый класс (его будущие члены) должен быть абсолютно доступен в производном классе. Первый оператор функции main() - объявление указателя на объект класса A. Затем следует определение объекта-представителя класса A, следом - настройка указателя на этот объект. Естественно, при этом используется операция взятия адреса. Всё это давно известно и очень просто. Следующие две строки являются определениями пары объектов, которые являются представителями двух разных производных классов…

За объявлениями объектов в программе располагаются строки, которые позволяют настроить указатель на базовый класс на объект производного класса. Для настройки указателя на объект производного класса нам не потребовалось никаких дополнительных преобразований. Здесь важно только одно обстоятельство. Между классами должно существовать отношение наследования. Таким образом, проявляется важное свойство объектно-ориентированного программирования: УКАЗАТЕЛЬ НА БАЗОВЫЙ КЛАСС МОЖЕТ ССЫЛАТЬСЯ НА ОБЪЕКТЫ - ПРОИЗВОДНЫХ КЛАССОВ.

указатель this

объект содержит свой экземпляр полей класса. Методы класса находят-з памяти в единственном экземпляре и используются всеми объектами совме-г.: этому необходимо обеспечить работу методов с полями именно того объ-] я которого они были вызваны. Это обеспечивается передачей в функцию гого параметра this, в котором хранится константный указатель на вызвав-функцию объект. Указатель thi s неявно используется внутри метода для ■ж на элементы объекта. В явном виде этот указатель применяется в основ-ч возвращения из метода указателя (return this;) или ссылки (return - вызвавший объект.

пюстрации использования указателя this добавим в приведенный выше tr новый метод, возвращающий ссылку на наиболее здорового (поле двух монстров, один из которых вызывает метод, а другой передается

1 качестве параметра (метод нужно поместить в секцию public описания

S the_best(monstr &М){ ' -ealth > M.getJiealthO) return *this; return M:

... monstr Vasia(50), Super(200);

// Новый объект Best инициализируется значениями полей Super: monstr Best = Vasia.the_best(Super);

Указатель this можно также применять для идентификации поля класса в том случае, когда его имя совпадает с именем формального параметра метода. Другой способ идентификации поля использует операцию доступа к области видимости:

void cure(int health, int ammo){

this -> health += health: // Использование this monstr:: ammo += ammo; // Использование операции ::

}

31.Члены данных объекта и указатели на члены данных класса.

Указатели на члены

Можно брать адрес члена класса. Операция взятия адреса функции-члена часто оказывается полезной, поскольку цели и способы применения указателей на функции, о которых мы говорили в $$4.6.9, в равной степени относятся и к таким функциям. Указатель на член можно получить, применив операцию взятия адреса & к полностью уточненному имени члена класса, например, &class_name::member_name. Чтобы описать переменную типа "указатель на член класса X", надо использовать описатель вида X::*. Например:

#include <iostream.h>

struct cl

{

char* val;

void print(int x) { cout << val << x << '\n'; }

cl(char* v) { val = v; }

};

Указатель на член можно описать и использовать так:

typedef void (cl::*PMFI)(int);

int main()

{

cl z1("z1 ");

cl z2("z2 ");

cl* p = &z2;

PMFI pf = &cl::print;

z1.print(1);

(z1.*pf)(2);

z2.print(3);

(p->*pf)(4);

}

Использование typedef для замены трудно воспринимаемого описателя в С достаточно типичный случай. Операции .* и ->* настраивают указатель на конкретный объект, выдавая в результате функцию, которую можно вызывать. Приоритет операции () выше, чем у операций .* и ->*, поэтому нужны скобки.

Во многих случаях виртуальные функции ($$6.2.5) успешно заменяют указатели на функции.