17124

Використання віртуальних і покажчиків для роботи з об'єктами класів

Лабораторная работа

Информатика, кибернетика и программирование

Лабораторна робота № 33 Тема: Використання віртуальних і покажчиків для роботи з об'єктами класів Ціль роботи: вивчити і навчитися використовувати віртуальні функції в мові С. Обладнання: ПКПО Borland C Теоретичні відомості Віртуальні функціїчлени з'являються в к...

Украинкский

2013-06-29

51.5 KB

1 чел.

Лабораторна робота № 33

Тема: Використання віртуальних і покажчиків для роботи з об'єктами класів

Ціль роботи: вивчити і навчитися використовувати віртуальні функції в мові С.

Обладнання: ПК,ПО Borland C++

Теоретичні відомості

Віртуальні функції-члени з'являються в класі c ключовим словом virtual.

Якщо базовий клас (БК) base містить віртуальну функцію (virtual) vf () і похідний клас (ПК) derived також містить цю функцію, то при виклику функції vf() для об'єкта базового класу ми одержимо base:: vf(), а для об'єкта похідного класу ми одержуємо derived::vf(). Наприклад:

Базовий клас

Похідний клас

struct base

{…..

virtual void vf (void);

void f (void);

};

base_1

class

{…

public:

virtual void vf(void)=0

void f(void);

};

struct derived : public base

{…..

virtual void vf (void);

// virtual в останньому

// ПК можна опустити

void f (void);

};

derived d;  // об'єкт производного класу

d.vf(); // виклик функції класу d

// erived::vf()

d.f();  // виклик функції класу

// derived::f()

base* bp = &d;  // покажчик на

// БК адресує об'єкт ПК

bp->vf ();  // виклик віртуальної

// функції derived::vf()

bp->f ();  // виклик функції-члена

// класу base

// base:: f()

Тип об'єктів класів з віртуальними функціями визначається під час виконання програми.

Тому при викликах за допомогою покажчика bp на БК функцій vf() і f() для об'єкта ПК з ім'ям d викликаються, відповідно, derived::vf(), але base::vf(). Виклик потрібної віртуальної функції vf() залежить від типу об'єкта, для якого вона викликається (derived d), у той час як виклик невіртуальної функції f() залежить тільки від типу покажчика (base*bp), що адресує даний об'єкт.

Якщо похідний клас містить функцію з тим же ім'ям, що й ім'я віртуальної функції в базовому класі, то вони повинні мати той самий тип. Функція vf() у ПК від БК, у якому міститься віртуальна функція vf(), також вважається віртуальною. Віртуальна функція може бути визначена в базовому класі. Віртуальну функцію, що уже визначена в базовому класі, у похідному класі можна не визначати. У цьому випадку при використанні покажчика на БК для адресації ПК при всіх звертаннях використовується функція, визначена в базовому класі. Якщо віртуальна функція в класі закінчується нулем (=0), то вона називається чистою віртуальною функцією. Чиста віртуальна функція не має визначення в базовому класі, але визначається в похідних. Клас, що містить хоча б одну таку функцію, називається абстрактним. Не можна створити об'єкт абстрактного класу.

Віртуальні базові класи

При множинному спадкуванні базовий клас не може задаватися в похідному класі більш одного разу. Однак, базовий клас можна передавати похідному  класу більш одного разу побічно:

class B { ... };

class D : B, B { ... }:

// неприпустимо

class X : public B { ... };

class Y : public B { ... };

class Z : public X, public Y { ... };  // припустимо

У даному випадку кожен об'єкт класу Z буде мати два підобъекта класи В. Для усунення цієї проблеми до специфікатора базового класу додають ключове слово virtual. Наприклад:

class X : virtual public B { ... };  // тепер У  є  віртуальним  базової

класом

class Y : virtual public B { ... };

class Z : public X, public Y { ... }  // клас Z має тільки один підобъект класу В.

Віртуальні деструктори

Конструктори не можуть бути віртуальними. Деструктор може бути оголошений як віртуальний (virtual). Це дозволяє покажчику на базовий клас викликати необхідний деструктор у випадку, коли покажчик посилається на об'єкт похідного класу. Деструктор похідного класу від базового класу з віртуальним деструктором є віртуальним.

class color

{...

public:

virtual ~color();  // віртуальний

// деструктор для класу color

};

class red : public color

{...

public:

virtual~red();    // деструктор для red // також є віртуальним

};

class brightred : public red

{...

public:

virtual~brightred();      // деструктор для brightred також віртуальний

};

Розглянемо роботу з об'єктами оголошених класів. Покажчик на базовий клас може адресувати об'єкти похідних класів

Color *palette[3];  // оголошення масиву покажчиків на базовий клас

Palette[0] = new red;  // створення об'єкта класу red у купі

palette[1] = new brightred; // створення об'єкта класу brightred у купі

palette[2] = new color; // створення об'єкта базового класу в купі

Застосування оператора delete

delete palette[0];  // викликається деструктор для об'єкта класу red

delete palette[1];  // деструктор для об'єкта класу brightred

delete palette[2];  // запуск деструктора для об'єкта класу color

Однак, якщо жоден з деструкторів не був оголошений віртуальним, то вираження delete palette[0], delete palette[1] і delete palette[2] викликають тільки деструктор для базового класу color, на який оголошений масив покажчиків. Це приведе до неправильного знищення перших двох елементів, що фактично мали тип red і brightred. Виклики віртуальних деструкторів компонуються під час виконання програми й об'єкти самі визначають, який деструктор треба викликати.

 

Приклад програми на С++

#include<iostream.h>

class palyvo

{public:

virtual int vs()

{s=a-(b+c);

 return s;}

void coutr();

palyvo();

protected:

char*post;

char*pok;

double a,b,c,s;

};

class benzin:public palyvo

{public:

virtual int vs()

{s=a-(b+c);

 return s;}

benzin();

};

class nafta:public benzin

{public:

virtual int vs()

{s=a-(b+c);

 return s;}

nafta();

};

void main()

{palyvo*p[3];

p[0]=new benzin;

p[1]=new nafta;

p[2]=new palyvo;

p[0]->vs();

p[1]->vs();

p[2]->vs();

cout<<"\nbenzin";

p[0]->coutr();

cout<<"\nnafta";

p[1]->coutr();

cout<<"\npalyvo";

p[2]->coutr();

delete p[0],p[1],p[2];

}

void palyvo::coutr()

{cout<<"\nob'em reservnih palyva: "<<s;

cout<<"\nob'em: "<<a;

cout<<"\nob'em sklada: "<<b;

cout<<"\nob'em osnovnogo zapasa palyva: "<<c;

cout<<"\nPostavshiki: "<<post;

cout<<"\nPokupateli: "<<pok;

}

palyvo::palyvo()

{a=10000; b=5000; c=4999;

post="Lukoil";

pok="TNK";

}

benzin::benzin()

{a=5000; b=3000; c=1000;

post="Lukoil";

pok="Gas";

}

nafta::nafta()

{a=78999; b=999;

c=500;

post="GAS";

pok="Gefest";

}

Хід роботи

1.Вивчити теоретичні відомості.

2.Відповідно до індивідуального завдання на базі лабораторної роботи №22 розробити алгоритм роботи з об'єктами базових і похідних класів з використанням покажчиків на базові і похідні класи. 3.При необхідності довести ієрархію класів до 3-4-х рівнів.

4.Набрати програму на комп'ютері й усунути помилки.

5.Одержати результат.

6.Оформити звіт.

7.Підготуватися до захисту лабораторної роботи, вивчивши контрольні питання по даній темі.

Вимоги до змісту звіту приведені в лабораторній   роботі   №1.

Контрольні запитання

1.Які функції-члени називаються убудованими (inline)?

2.Які функції-члени називається перевантаженими?

3.Які функції-члени називаються що заміщають?

4.Які функції- члени називається віртуальними?

5.Чи можна адресувати об'єкти ПК за допомогою покажчиків на загальний БК, на попередній БК по ієрархії?

6.Назвіть правила використання покажчиків для роботи з об'єктами БК і ПК.

7.Коли необхідне визначення віртуальної функції в базовому класі?

8.Який клас називається абстрактним?

9.Чи можна створити об'єкт абстрактного класу?

10.Яка функція називається чисто віртуальної?

11.Чи можна установити в процесі компіляції яка функція буде викликатися при використанні покажчиків для роботи з об'єктами?

12.Чи можуть конструктори і деструктори бути віртуальними? Чим це викликано?

13.Як виробляється розміщення об'єктів класів у "купі"?

14.Як виробляється виділення і звільнення пам'яті для динамічно створюваних об'єктів?

15.Коли виробляється перебування віртуальної функції, яку необхідно викликати для заданого об'єкта ПК, якщо для адресації об'єкта ПК використовується покажчик на БК.?

16.Яка невіртуальна функція буде викликана в зазначеному випадку і чому?

17.Для чого чи як з'являються віртуальні класи?


 

А также другие работы, которые могут Вас заинтересовать

5174. Предмет, задачи и методы генетики. 756 KB
  Предмет, задачи и методы генетики. Генетика - наука об основных закономерностях наследственности и изменчивости. Наследственность - это свойство живых организмовприобретать в процессе онтогенеза признаки сходные с родительскими организмами и п...
5175. Понятия, ген, генотип и фенотип. Фенотипическая и генотипическая изменчивость, мутации 247.5 KB
  Понятия, ген, генотип и фенотип. Фенотипическая и генотипическая изменчивость, мутации. При изучении закономерностей наследования обычно скрещивают особи, отличающиеся друг от друга альтернативными признаками, например желтый и зеленый цвет, гладкая...
5176. Концепции клеточного строения и функционирования живой материи 699 KB
  Концепции клеточного строения и функционирования живой материи I. История открытия клеточного строения живых организмов Все живые организмы построены из клеток. Одноклеточные организмы (бактерии, простейшие, многие водоросли и грибы) состоят из одно...
5177. Закон гомологических рядов 37.5 KB
  Закон гомологических рядов Обработка обширного материала наблюдений и опытов, детальное исследование изменчивости многочисленных линнеевских видов (линнеонов), огромное количество новых фактов, полученных главным образом при изучении культурных раст...
5178. Генетика бактерий. Особенности морфологической организации ядерного аппарата бактерий 67 KB
  Генетика бактерий На модели бактерий и вирусов были открыты все основные закономерности генетики. 1.Особенности морфологической организации ядерного аппарата бактерий: - не имеет ядерной мембраны, ядрышка, носит название нуклеоид - носителем ...
5179. Основы генетики 92.5 KB
  Основы генетики. Генетика - наука о наследственности и изменчивости. Наследственность - это свойство дочерних организмов быть похожими на своих родителей морфологическими, физиологическими, биохимическими и другими признаками и особенностями...
5180. Характеристика генетического аппарата бактерий 4.97 MB
  Характеристика генетического аппарата бактерий Организация генома. Генетический аппарат бактерий представлен бактериальной хромосомой, внехромосомными факторами наследственности - плазмидами, а также входящими в их состав мобильными генетическ...
5181. Генетика и биополитический конфликт в 20 веке. Евгеника 50.5 KB
  Евгеника В 1883 году англичанин Фрэнсис Гальтон – кузен Чарльза Дарвина - заложил основы евгеники. Он считал, что большинство признаков у человека являются наследственными, и их можно улучшить путём контролируемых браков. В позитивной гене...
5182. Генетика и человек 241.5 KB
  Почему люди интересуются генетикой? Люди интересуются генетикой давно, правда, не всегда они называли вопросы наследования определенных признаков генетикой. Проще говоря, издревле человека интересовало, почему дети, как правило, похожи на своих роди...