69725

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

Лекция

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

Як вказано в коментарях, класи derivedl і derived2 є спадкоємцями класу base. Проте клас deribed3 є похідним від обох класів derived2 і derived1. (Таке наслідуванно називається діамантовим). Отже, в об’єкті класу derived3 містяться дві копії об’єкту класу base.

Украинкский

2014-10-09

42 KB

0 чел.

Тема 3: Віртуальні базові класи

При множинному наслідуванні може виникнути неоднозначність. Розглянемо, наприклад, наступну неправильну програму.

//  Ця програма містить  помилку і не  компілюється.

#include <iostream>

using namespace std;

class base   {

public:

int  i;

};

// Клас derivedl є спадкоємцем класу base.

class derivedl : public base {

public:

int j ;

};

// Клас derived2 є спадкоємцем класу base 

class derived2 : public base {

public:

int k;

};

/* Клас derived3 є спадкоємцем класів derivedl і derived2. Отже, в класі

derived3 існують дві копії класу base! */

class derived3 : public derivedl, public derived2 {

public:

int sum;

};

int main() {

derived3 ob;

ob.i = 10; ob.j = 20; ob.k = 30;

// Неоднозначність, яка змінна i мається

// Тут змінна i також визначена неоднозначно.

ob. sum = ob. i + ob. j + ob.k;

// Тут змінна i також визначена неоднозначно

cout << ob.i << " ";

cout « ob.j « " " « ob.k « " ";

cout << ob.sum;

return 0;

}

Як вказано в коментарях, класи derivedl і derived2 є спадкоємцями класу base. Проте клас deribed3 є похідним від обох класів derived2 і derived1. (Таке наслідуванно називається діамантовим). Отже, в об'єкті класу derived3 містяться дві копії об'єкту класу base. Таким чином, вираз

 ob.i  =  20;

у якому відбувається звернення до змінної i, стає неоднозначним, оскільки невідомо, з об'єкту якого класу слід узяти цю змінну: derivedl або derived2. Володіючи двома копіями об'єкту класу base, об'єкт класу ob містить два екземпляри змінної ob.i! Як видимий, цей оператор в принципі неоднозначний.

Цю програму можна виправити двома способами. По-перше, до змінній i можна застосувати оператора дозволу області видимості. Наприклад, наступна програма працює абсолютно правильно

//   У  цій програмі для  явного  вибору  змінної  i

//   застосовується  оператор дозволу  області видимості.

#include  <iostream>

using namespace  std;

class  base   {

public:

int   i ;

};

// Клас derivedl є спадкоємцем класу base

class derivedl : public base {

public:

int j ;

};

// Клас derived2 є спадкоємцем класу base 

class derived2 : public base {

public:

int k;

};

/* Клас derived3 є спадкоємцем класів derivedl і derived2 одночасно.

Отже, в кожному його об'єкті містяться дві копії об'єкту класу base! */

class derived3 : public derivedl, public derived2 {

public:

int sum;

};

int main() {

derived3 ob;

ob.derivedl::i = 10; // Неоднозначність усунена

// використовується змінна i з класу derivedl .

ob.j = 20; ob.k = 30;

// Неоднозначність усунена

ob.sum = ob.derivedl::i + ob.j + ob.k;

// Неоднозначність усунена

cout « ob.derivedl::i « " ";

cout « ob.j « " " « ob.k « " "; cout << ob.sum;

return 0;

}

Як видимий, оператор дозволу області видимості "::" дозволяє явно вибрати варіант похідного класу. Проте це рішення породжує нові проблеми. Що якщо насправді потрібна лише одна копія об'єкту класу base? Чи можна запобігти дублюванню об'єктів класу base в об'єкті класу derivad3? На обидва питання можна відповісти позитивно. Вирішення цих проблем засноване на застосуванні віртуальних базових класів (virtual base classes).

Якщо базовий клас має декілька спадкоємців, його дублюванню можна запобігти. Для цього в оголошенні похідного класу перед ім'ям базового класу слід поставити ключове слово virtual. Наприклад, попередню програму можна виправити таким чином.

class derivedl : virtual public base {

public:

int j ;

};

// Клас derivedl є спадкоємцем віртуального класу base.

class derived2 : virtual public base {

public:

int k;

};

/* Клас derived3 є спадкоємцем класів derivedl і derived2.

Цього разу його об'єкт містить лише одну копію об'єкту базового класу. */

class derived3 : public derivedl, public derived2 {

public:

int sum;

};

Як видимий, перед ім'ям базового класу в специфікації похідного класу стоїть ключове слово virtual. Тепер обидва класи derivedl і derived2 є спадкоємцями віртуального базового класу base, і будь-які їх спадкоємці міститимуть лише одну копію класу base. Отже, об'єкт класу derived3 містить копію об'єкту класу base, і вираз ob.i=10 стає абсолютно правильним і однозначним.

Слід мати на увазі, що, хоча класи derivedl і derived2 оголосили клас base віртуальним, його об'єкти будуть як і раніше частиною об'єктів будь-якого з цих типів. Наприклад, наступний фрагмент є абсолютно правильним.

//   Визначуваний об'єкт  класу derivedl 

derivedl myclass; myclass.i  =   88;

Відмінність між звичайним базовим класом і віртуальним виявляється, тільки коли об'єкт успадковує декілька об'єктів одного і того ж базового класу. Якщо використовується віртуальний базовий клас, то його об'єкт тільки один раз копіюється в кожен об'єкт похідного класу. Інакше виникає неоднозначність.


 

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

77000. Протокол об административном правонарушении: содержание, требования, предъявляемые к протоколу, сроки его составления, случаи, когда протокол не составляется 28.31 KB
  Протокол об административном правонарушении: содержание требования предъявляемые к протоколу сроки его составления случаи когда протокол не составляется. Протокол об административном правонарушении процессуальный документ свидетельствующий о совершении данного противоправного деяния конечно предположительно. В Кодексе об административных правонарушениях установлены реквизиты протокола: дата и место составления; данные о его составителях; сведения о личности нарушителя; место время совершения и его существо; нормативный акт...
77001. Административное расследование. Основания для проведения, процессуальное оформление, сроки расследования 27.67 KB
  Составлению протокола об административном правонарушении может предшествовать административное расследовании на основании определения вынесенного должностным лицом уполномоченным составлять такой протокол за предусмотренные КоАП РФ административные правонарушения: монопольного валютного законодательства законодательства о защите прав потребителей охраны окружающей среды пожарной безопасности дорожного движения и на транспорте и др. Административное расследование проводится если осуществляются экспертиза или иные процессуальные...
77002. Место и порядок подготовки дела об административном правонарушении к рассмотрению, разрешаемые вопросы и процессуальное оформление принятого решения 27.19 KB
  Место и порядок подготовки дела об административном правонарушении к рассмотрению разрешаемые вопросы и процессуальное оформление принятого решения. Рассмотрение дела по существу начинается с момента получения субъектом административной юрисдикции протокола об административном правонарушении за которым следует подготовка дела к рассмотрению. Субъекты юрисдикции в порядке подготовки к рассмотрению дела выясняют: относится ли к их компетенции рассмотрение дела; имеются ли обстоятельства исключающие рассмотрение ими дела; правильно ли...
77003. Порядок рассмотрения и разрешения дела об административном правонарушении, сроки рассмотрения, решения, принимаемые по результатам рассмотрения дела 26.52 KB
  Порядок рассмотрения и разрешения дела об административном правонарушении сроки рассмотрения решения принимаемые по результатам рассмотрения дела. Подготовка к рассмотрению дела об административном правонарушении Судья орган должностное лицо при подготовке к рассмотрению дела об административном правонарушении выясняют следующие вопросы: 1 относится ли к их компетенции рассмотрение данного дела; 2 имеются ли обстоятельства исключающие возможность рассмотрения данного дела судьей членом коллегиального органа должностным лицом; 3...
77004. Содержание постановлений и определений, принятых по результатам рассмотрения дела об административном правонарушении 27.61 KB
  Содержание постановлений и определений принятых по результатам рассмотрения дела об административном правонарушении. По результатам рассмотрения дела об административном правонарушении может быть вынесено постановление. В постановлении по делу об административном правонарушении должны быть указаны: должность фамилия имя отчество судьи должностного лица наименование и состав коллегиального органа вынесших постановление; дата и место рассмотрения дела; сведения о лице в отношении которого рассмотрено дело; обстоятельства...
77005. Обжалование и опротестование постановления по делу об административном правонарушении. Порядок и сроки обжалования (опротестования). Виды принимаемых решений 27.86 KB
  Обжалование и опротестование постановления по делу об административном правонарушении. Пересмотр постановлений и решений по делам об административных правонарушениях Правом на обжалование постановлений по административному делу обладают: лицо в отношении которого ведется административное дело; потерпевший; законный представитель физического лица; законный представитель юридического лица; защитник и представитель Постановление по делу об административном правонарушении может быть обжаловано: вынесенное судьей в вышестоящий суд;...
77006. Порядок вступления в силу вынесенного постановления. Основные положения исполнения постановления по делу об административном правонарушении 27.28 KB
  Основные положения исполнения постановления по делу об административном правонарушении. На стадии исполнения завершается производство исполняются принятые по делам постановления решения осуществляется карательное воздействие. Поэтому на стадии исполнения появляется много новых участников производства действуют особые принципы специфичны и содержание деятельности субъектов власти и статус наказанного. Отношения возникающие на стадии исполнения постановлений о привлечении виновных юридических и физических лиц к административной...
77007. Особенности исполнения отдельных видов административных наказаний 27.01 KB
  Постановление о назначении административного наказания в виде предупреждения исполняется судьей органом должностным лицом вынесшими постановление путем вручения или направления копии постановления Исполнение постановления о наложении административного штрафа. Административный штраф должен быть уплачен лицом привлеченным к административной ответственности не позднее тридцати дней со дня вступления постановления о наложении административного штрафа в законную силу либо со дня истечения срока отсрочки или срока рассрочки. Сумма...
77008. Отсрочка и рассрочка исполнения постановления по делу об административном правонарушении Случаи прекращения исполнения постановления о назначении административного наказания 26.04 KB
  Отсрочка и рассрочка исполнения постановления по делу об административном правонарушении Случаи прекращения исполнения постановления о назначении административного наказания. При наличии обстоятельств вследствие которых исполнение постановления о назначении административного наказания в виде административного ареста лишения специального права или в виде административного штрафа невозможно в установленные сроки судья орган должностное лицо вынесшие постановление могут отсрочить исполнение постановления на срок до одного месяца....