Лекции (8) (Презентации лекций (PDF))
Описание файла
Файл "Лекции (8)" внутри архива находится в папке "Презентации лекций (PDF)". PDF-файл из архива "Презентации лекций (PDF)", который расположен в категории "". Всё это находится в предмете "практикум (прикладное программное обеспечение и системы программирования)" из 4 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .
Просмотр PDF-файла онлайн
Текст из PDF
Единичное наследованиеКонструкторы, деструкторы и operator= не наследуются!!!class < имя derived-cl > : < способ наследования > < имя base-cl > {...};Пример:struct A { int x; int y; };struct B : A { int z; };class C : protected A { int z; };.........A a;B b;b.x = 1;b.y = 2;b.z = 3;a = b;A a, *pa;B b, *pb;pb = &b;pa = pb;pb = ( B* ) pa;A * pa;C c, * pc = &c;pc -> z; // ошибка: доступ к закрытому полюpc -> x; // ошибка: доступ к защищённому полюpa = ( A * ) pc;pa -> x; // правильно: поле A::x – открытоеB:: A::int x;int y;int z;1Cокрытие имёнstruct A {int f ( int x , int y);int g ();int h;};struct B : public A {int x;void f ( int x );void h ( int x );};.......A a, *pa;B b, *pb;pb = &b;pb -> f (1);// вызывается B::f(1)pb -> g ();// вызывается A::g()pb -> h = 1;// Err.! функция h(int) – не L-value выражениеpa = pb; pa -> f (1);// Err.! функция A::f(1) имеет 2 параметраpb = &a;// Err.! расширяющее присваивание // pb = (B*)&apb -> f (1);// Возможна Err, если в f(1) используется x из В 2Видимость и доступность именint x;void f (int a) { cout << “ :: f " << a << endl; }Пример.class A {int x;public:void f (int a) { cout << “ A:: f " << a << endl; }};class B : public A {public:void f (int a) { cout << “ B:: f " << a << endl; }void g ();};void B::g() {f(1);A::f(1);::f(1);//x = 2;}// вызов B::f(1)// вызов глобальной void f(int)//ошибка!!! – осущ.
доступ к закрытому члену класса А3Вызов конструкторов базового и производногоклассов. Пример.class A { ... };class B : public A {public:B ();B (const B &); // есть явно описанный конструктор копирования...};class C : public A {public:// нет явно описанного конструктора копирования...};int main ( ) {B b1;// A (), B ()B b2 = b1;// A (), B (const B &)C c1;// A (), C ()C c2 = c1;// A (const A &), C (const C &)...}4Классы student и student5class student {char * name;int year;double est;public:student ( char* n, int y, double e);void print () const;~student ();};class student5: public student {char * diplom;char * tutor;public:student5 ( char* n, double e, char* d, char* t);void print () const;// эта print скрывает print из базового класса~student5 ();};student5:: student5 ( char* n, double e, char* d, char* t) : student (n, 5, e) {diplom = new char [strlen (d) + 1];strcpy (diplom, d);tutor = new char [strlen (t) + 1];strcpy (tutor, t);}student5 :: ~student5 () {delete [ ] diplom;delete [ ] tutor;}void student5 :: print () const {student :: print (); // name, year, estcout << diplom << endl;cout << tutor << endl:}5Использование классов student и student5void f ( ) {student s (“Kate”, 2, 4.18), * ps = & s;student5 gs (“Moris”, 3.96, “DIP”, “Nick”), * pgs = & gs;ps -> print();pgs -> print();// student :: print ();// student5 :: print ();// base = derived – допустимо с преобразованием по// умолчанию.ps -> print(); // student :: print () – функция выбирается статически// по типу указателя.ps = pgs;6Виртуальные методыМетод называется виртуальным, если при его объявлении в классе используетсяквалификатор virtual.Класс называется полиморфным, если содержит хотя бы один виртуальныйметод.Объект полиморфного класса называют полиморфным объектом.Чтобы динамически выбирать функцию print () по типу объекта, на которыйссылается указатель, переделаем наши классы т.о.:class student {…public:...virtual void print ( ) const ;};class student5 : public student {…public:...[virtual] void print ( ) const ;};Тогда:ps = pgs;ps -> print(); // student5 :: print () – ф-я выбирается динамически по типу7// объекта, чей адрес в данный момент хранится в указателеВиртуальные деструкторыСовет: для полиморфных классов делайте деструкторывиртуальными!!!void f () {student * ps = new student5 (“Moris”, 3.96, “DIP”, “Nick”);…delete ps; // вызовется ~student, и не вся память зачистится}Но если:virtual ~student (); и[virtual] ~student5 ();то вызовется ~student5(), т.к.
сработает динамическийполиморфизм.8Механизм виртуальных функций(механизм динамического полиморфизма)1.!Виртуальность функции, описанной с использованиемслужебного слова virtual не работает сама по себе, онаначинает работать, когда появляется класс, производный отданного, с функцией с таким же прототипом.2.Виртуальные функции выбираются по типу объекта, накоторый ссылается указатель (или ссылка).3.У виртуальных функций должны быть одинаковые прототипы.Исключение составляют функции с одинаковым именем исписком формальных параметров, у которых тип результатаесть указатель или ссылка на себя (т.е.
соответственно набазовый и производный класс).4.Если виртуальные функции отличаются только типомрезультата (кроме случая выше), генерируется ошибка.5.Для виртуальных функций, описанных с использованиемслужебного слова virtual, с разными прототипами работаетмеханизм сокрытия имен.9Абстрактные классыАбстрактным называется класс, содержащий хотя бы одну чистую виртуальнуюфункцию.Чистая виртуальная функция имеет вид: virtual тип_рез имя ( сп_фп ) = 0;Пример:class shape {public:virtual double area () = 0;};class rectangle: public shape {double height, width;public:double area () {return height * width;}};class circle: public shape {double radius;public:double area () {return 3.14 * radius * radius;}};#define N 100....shape* p [ N ];double total_area = 0;....for (int i =0; i < N; i++)total_area += p[i] -> area();....10ИнтерфейсыИнтерфейсами называют абстрактные классы,которые- не содержат нестатических полей-данных, и- все их методы являются открытыми чистымивиртуальными функциями.11Реализация виртуальных функцийclass A {int a;public:virtual void f ();virtual void g (int);virtual void h (double);};class B : public A {public:int b;void g (int);virtual void m (B*);};Тогда С с; ~apvtblbcclass C : public B {public:int c;void h (double);virtual void n (C*);};vtbl для с ~C c;A *p = &c;p -> g (2); ~ (* ( p -> pvtbl [1]) ) (p, 2); // p = this&A:: f&B:: g&C:: h&B:: m&C:: n12Виртуальные функции.
Пример 1.class X {public:void g ( ) {cout << "X::g\n";h ( );}virtual void f() {g ( );h ( );}virtual void h ( ) {cout << "X::h\n";}};int main () {Y b;X *px = &b;px -> f();px -> g();return 0;}// Y::g// X::gclass Y : public X {public:void g ( ) {cout << "Y::g\n";h ( );}virtual void f ( ) {g ( );h ( );}virtual void h ( ) {cout << "Y::h\n";}};Y::hY::hY::h13Виртуальные функции. Пример 2.struct A {virtual int f (int x, int y) {cout << "A : :f (int, int) \n";return x + y;}virtual void f ( int x ) {cout << "A :: f( ) \n";}};struct B : A {void f ( int x ) {cout << "B :: f( ) \n";}};struct C : B {virtual int f (int x, int y) {cout << "C :: f (int, int) \n";return x + y;}};int main () {B b, *pb = &b;C c;A * pa = &b;pa -> f (1);// B::f();pa -> f (1, 2); // A::f(int, int)//pb -> f (1, 2); // Err.! Эта f не виднаA & ra = c;ra.f(1,1);// C::f(int, int)B & rb = c;//rb.f(0,0); // Err.! Эта f не виднаreturn 0;}14Виртуальные функции.
Пример 3.struct B {virtual B& f () { cout << “ f ( ) from B\n"; return *this;}virtual void g (int x, int y = 7) { cout << "B::g\n"; }};struct D : B {virtual D& f ( ) { cout << “ f ( ) from D\n"; return *this; }virtual void g (int x, int y) { cout << "D::g y = " << y << endl; }};int main () {D d;B b1, *pb = &d;pb -> f();// f ( ) from Dpb -> g(1);// D::g y = 7pb -> g(1,2);// D::g y = 2return 0;}Если значение параметра y по умолчанию будет в функции g класса D, ав базовом не будет, компилятор на вызов pb - > g(1) выдаст ошибку.15.