Содержание
-
Виртуальные функции. Абстрактные классы. Дружественные классы Наследование
-
Простой пример использования виртуальной функции
#include #include using namespace std; class base { public: int i; base(int x) { i = x; } virtual void func() { cout
-
int main() { base *p; base obj_base(10); deri1 obj_deri1 (10); deri2 obj_deri2(10); p = &obj_base; p->func(); // функция func() класса base p = &obj_deri1; p->func(); // функция func() производного класса deri1 p = &obj_deri2; p->func(); // функция func() производного класса deri2 getch(); return 0; }
-
Иерархический порядок наследования виртуальных функций
base deri1 deri2
-
//Виртуальные функции имеют иерархический порядок наследования #include #include using namespace std; class base { public: int i; base(int x) { i = x; } virtual void func() { cout
-
int main() { base *p; base obj_base10); deri1 obj_deri1(10); deri2 obj_deri2(10); p = &obj_base; p->func(); // функция func() базового класса p = &obj_deri1; p->func(); // функция func() производного класса deri1 p = &obj_deri2; p->func(); // функция func() базового класса getch(); return 0; }
-
Позднее связывание
//Работа виртуальной функции при наличии случайных событий во время выполнения программы #include #include #include using namespace std; class base { public: int i; base(int x) { i = x; } virtual void func() { cout
-
int main() { base *p; deri1 obj_deri1(10); deri2 obj_deri2(10); int i, j; for(i=0; ifunc(); // вызов подходящей версии функции } getch(); return 0; }
-
Абстрактный класс
//Базовый класс – абстрактный. #include #include using namespace std; class base// объявление абстрактного класса { public: base() {} // конструктор ~base () {} // деструктор virtual void get() =0; // чистая //виртуальная функция }; class deri1: public base//объявление //производного класса { protected: double x; public: deri1(double bx) // конструктор {x = bx;} ~deri1 () // деструктор { cout
-
class deri2: public deri1 //объявление производного класса { double y; public: deri2(double bx,double by):deri1(bx) // конструктор {y = by; } ~deri2 () // деструктор { cout get(); P = new deri1(1); P -> get(); // 1 P = new deri2(2,3); P -> get(); // 2 3 getch(); }
-
ДОСТУП К ЭЛЕМЕНТАМ БАЗОВОГО КЛАССА В КЛАССЕ-НАСЛЕДНИКЕ Доступность элементов базового класса из классов-наследников изменяется в зависимости от спецификаторов доступа в базовом классе и спецификатора наследования:
-
Программы могут обращаться к частным (private) элементам класса только с помощью функций-элементов этого же класса. Использование частных элементов класса вместо общих во всех ситуациях, где это только возможно, уменьшает возможность программы испортить значения элементов класса, так как программа может обращаться к таким элементам только через интерфейсные функции (которые управляют доступом к частным элементам). Однако в зависимости от использования объектов программы можно существенно увеличить производительность, позволяя одному классу напрямую обращаться к частным элементам другого, что уменьшает время выполнения на вызов интерфейсных функций.
-
C++ позволяет определить класс в качестве друга (friend} другого класса и разрешает классу-другу доступ к частным элементам этого другого класса
Дружественные классы могут обращаться напрямую к частным элементам другого класса. Частные элементы класса защищают данные класса следует ограничить круг классов-друзей только теми классами, которым действительно необходим прямой доступ к частным элементам искомого класса. C++ позволяет ограничить дружественный доступ определенным набором функций. Чтобы указать C++, что один класс является другом (friend) другого класса, следует указать ключевое слово friend и имя соответствующего класса-друга внутрь определения другого класса.
-
Форма доступа – дружественные структуры:
Дружественные функции; Дружественные классы; Дружественные функции-элементы. Дружественная функция по отношению к какому-либо классу получает такие же привилегии доступа, какими обладает функция-элемент этого класса. Например, в следующем примере функция frd() объявлена другом класса cl:class cl {... public:friend void frd();...};
-
#include #include classXXX; /*Неполное объявление класса. Оно необходимо для объявления типа параметра функции-члена для следующего класса*/ class MMM { private: int m1; public: MMM(intval); void TypeVal(char *ObjectName, XXX& ClassParam); }; MMM::MMM(intval) { m1 = val;} /*Определение функции-члена TypeVal располагается после объявления класса XXX. Только тогда транслятор узнает о структуре класса, к которому должна получить доступ функция MMM::TypeVal.*/
-
class XXX { friend class YYY; friend void MMM::TypeVal(char *ObjectName, XXX& ClassParam); friend void TypeVal(XXX& ClassParamX, YYY& ClassParamY); /*В классе объявляются три друга данного класса: класс YYY, функция-член класса MMM, простая функция TypeVal. В класс XXX включаются лишь объявления дружественных функций и классов. Все определения располагаются в других местах - там, где им и положено быть - в своих собственных областях видимости.*/ private: int x1; public: XXX(intval); }; XXX::XXX(intval) { x1 = val;} void MMM::TypeVal(char *ObjectName, XXX& ClassParam) { cout
-
class YYY { friend void TypeVal(XXX& ClassParamX, YYY& ClassParamY); private: int y1; public: YYY(intval); void TypeVal(char *ObjectName, XXX& ClassParam); }; YYY::YYY(intval) { y1 = val; } void YYY::TypeVal(char *ObjectName, XXX& ClassParam) { cout
-
void main() { XXX mem1(1); XXX mem2(2); XXX mem3(3); YYY disp1(1); YYY disp2(2); MMM special(0); disp1.TypeVal("mem1", mem1); disp2.TypeVal("mem2", mem2); disp2.TypeVal("mem3", mem3); special.TypeVal("\n mem2 from special spy:", mem2); TypeVal(mem1, disp2); TypeVal(mem2, disp1); } void TypeVal(XXX& ClassParamX, YYY& ClassParamY) { cout
-
Пример:
Class book { public: book (char *, char *, char *); void show_book(void); friendlibrarian; private: char title [60] ; char author[60]; char catalog[30]; }; Исправить следующую программу!
-
#include #include class book { public: book (char *, char *, char *); void show_book(void); friend librarian; private: char title[60] ; char author[60]; char catalog[30]; }; book::book(char *title, char *author, char *catalog) { strcpy(book::title, title); strcpy(book::author, author) ; strcpy(book::catalog, catalog); } void book::show_book(void) { cout
-
class librarian { public: void chan_catal(book *, char *); char *get_catalog(book); }; void librarian::chan_catal(book *this_book, char *new_catalog) { strcpy(this_book->catalog, new_catalog); } char *librarian: :get_catalog(book this_book) { static char catalog[30]; strcpy(catalog, this_book.catalog); return(catalog) ; } void main(void) { book programming( «Язык C++", «Пратта", «N2.01"); librarian library; programming.show_book(); library.chan_catal(&programming, "Programming"); programming.show_book(); }
-
Резюме
Обычно единственный способ, с помощью которого программы могут обращаться к частным элементам класса, заключается в использовании интерфейсных функций. В зависимости от использования объектов иногда может быть удобным (или более эффективным с точки зрения скорости вычислений) разрешить одному классу обращаться к частным элементам другого. Для этого необходимо информировать компилятор C++, что класс является другом (friend). Компилятор, в свою очередь, позволит классу-другу обращаться к частным элементам требуемого класса. Для объявления класса другом, следует поместить ключевое слово friend и имя класса-друга в секцию public определения класса. Классы-друзья C++ обычно не связаны между собой узами наследования.
-
-
Дружественная данному классу функция
не является членом этого класса она не может быть вызвана из объекта класса, для которого она объявлена другом, при помощи операции доступа к члену класса (.); может быть функцией-членом другого ранее объявленного классапри этом само определение дружественной функции приходится располагать после объявления класса, другом которого была объявлена данная функция; не имеет this указателя для работы с классом, содержащим ее объявление в качестве дружественной функции. Дружба - это всего лишь дополнение принципа инкапсуляции; не имеет доступа к членам производного класса, чьи базовые классы содержали объявление этой функции. Дети не отвечают за отношения своих родителей; дружественные отношения не наследуются.
-
Лекция окончена Спасибо за внимание
Нет комментариев для данной презентации
Помогите другим пользователям — будьте первым, кто поделится своим мнением об этой презентации.