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.Для чого чи як з'являються віртуальні класи?


 

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

16735. Методика контроля параметров биотехнологических процессов в технологических схемах бактериального выщелачивания золота 64.5 KB
  Методика контроля параметров биотехнологических процессов в технологических схемах бактериального выщелачивания золота И. Б. Насридинов Г. 2000 г. УДК 349.283:552.57 Истощение богатых зон месторождений полезных ископаемых заставляет горнорудные кампании искать новые зале...
16736. Научные аспекты развития работ по подземному выщелачиванию урана 71.5 KB
  Научные аспекты развития работ по подземному выщелачиванию урана УДК 622 c Колпакова Е.В. Есаулов В.Н. Саттаров Г.С. Першин М.Е. Лильбок Л.А. 2009 г. Колпакова Е.В. руководитель группы ЦНИЛ НГМК; Есаулов В.Н...
16737. НОВЫЕ ПОДХОДЫ К ИЗВЛЕЧЕНИЮ БЛАГОРОДНЫХ МЕТАЛЛОВ НАНОРАЗМЕРНОЙ КРУПНОСТИ 27 KB
  НОВЫЕ ПОДХОДЫ К ИЗВЛЕЧЕНИЮ БЛАГОРОДНЫХ МЕТАЛЛОВ НАНОРАЗМЕРНОЙ КРУПНОСТИ Усманова Н.Ф. ИХХТ СО РАН В последнее время возрастающая роль в золотодобыче отводится корам выветривания. По данным информационноаналитического центра Минеральные ресурсы мира на 2007 год на ...
16738. ПОДЗЕМНОЕ ВЫЩЕЛАЧИВАНИЕ ЗОЛОТА 97 KB
  О ПОДЗЕМНОМ ВЫЩЕЛАЧИВАНИИ ЗОЛОТА М.И.Фазлуллин В.В.Шаталов Г.И.Авдонин Р.Н.Смирнова ФГУП ВНИИХТ Минатома России В.И.Ступин ООО НПП ГЕОТЭП Подземное выщелачивание ПВ металлов получило наибольшее развитие в мире в варианте скважинной системы отработки руд непоср
16739. ООО “НЕРЮНГРИ-МЕТАЛЛИК” – новый проект кучного выщелачивания 45 KB
  ООО €œНЕРЮНГРИМЕТАЛЛИК€ – новый проект кучного выщелачивания Гуминский В.И. Чёрный К.Н. ООО €œНерюнгриМеталлик€ создано 30 ноября 2000 г. Спустя 3 мес. 30 марта 2001 г. предприятием была получена лицензия ЯКУ01860БР с целевым назначением €œГеологическое изучение и добыча
16740. ОПТИМИЗАЦИЯ ТЕХНОЛОГИЧЕСКИХ ПАРАМЕТРОВ СКВАЖИННОГО ПОДЗЕМНОГО ВЫЩЕЛАЧИВАНИЯ ДРАГОЦЕННЫХ МЕТАЛЛОВ 486 KB
  Возросшая в последние годы потребность в золоте, как в валютном, так и в техническом металле, одновременно с истощением его запасов, способствовала началу более интенсивного развития технологии скважинного подземного выщелачивания драгоценных металлов
16741. Опыт кучного цианирования окисленной руды Урусайской площади 85 KB
  УДК 622.7.017:533.411.068.5 Опыт кучного цианирования окисленной руды Урусайской площадиАкчурина Р.Х. ведущий инженер ИМР; Ходжиметова Н.С. инженер ИМР; Попов Е.Л. зав. ОТПМС ИМР канд. техн. наук; Ахмедов Х. зав. лабораторией обогащения ИМР Кучное выщелачивание КВ как высокорент...
16742. Перспективы вовлечения в переработку отходов горно-перерабатывающего производства на базе золоторудных месторождений 123 KB
  Перспективы вовлечения в переработку отходов горноперерабатывающего производства на базе золоторудных месторождений УДК 622 c Шеметов П.А. Сытенков В.
16743. ПЕРСПЕКТИВЫ ИЗВЛЕЧЕНИЯ ЗОЛОТА МЕТОДОМ КУЧНОГО ВЫЩЕЛАЧИВАНИЯ В ХОЛОДНЫХ КЛИМАТИЧЕСКИХ РЕГИОНАХ РОССИИ 132.5 KB
  ПЕРСПЕКТИВЫ ИЗВЛЕЧЕНИЯ ЗОЛОТА МЕТОДОМ КУЧНОГО ВЫЩЕЛАЧИВАНИЯ В ХОЛОДНЫХ КЛИМАТИЧЕСКИХ РЕГИОНАХ РОССИИ Дементьев В.Е. к.т.н. Татаринов А.П. Гудков С.С. Григорьев С.Г Рязанова И.И. Необходимость вовлечения в переработку нетрадиционного сырья бедные и забалансов