• Главная
  • Карта сайта
Не найдено

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

  1. посилання

Оскільки клас може кілька разів виступати як непрямий базовий клас до похідному класу, в C ++ є спосіб оптимізувати функціонування таких базових класів. Віртуальні базові класи дозволяють економити простір і виключати неоднозначність в ієрархіях класів, в яких використовується множинне спадкування.

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

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

Коли створюється оголошення віртуального базового класу, в базових списках похідних класів вказується ключове слово virtual.

Розглянемо ієрархію класів, представлену на наступному малюнку, на якому показана імітація графа Lunch-Line.

Змодельований граф Lunch-Line

Як видно на малюнку, клас Queue є базовим для двох інших класів: CashierQueue і LunchQueue. Однак коли ці два класи об'єднуються і утворюють клас LunchCashierQueue, виникає наступна проблема: новий клас містить два підлеглих об'єкта типу Queue - один з CashierQueue, а інший з LunchQueue. На наступному малюнку показана концептуальна структура пам'яті (фактична структура пам'яті може бути оптимізована).

Змодельований об'єкт Lunch-Line

Змодельований об'єкт Lunch-Line

Зверніть увагу, що в об'єкті LunchCashierQueue є два підлеглих об'єкта Queue. У наступному коді міститься оголошення Queue як віртуального базового класу:

// deriv_VirtualBaseClasses.cpp // compile with: / LD class Queue {}; class CashierQueue: virtual public Queue {}; class LunchQueue: virtual public Queue {}; class LunchCashierQueue: public LunchQueue, public CashierQueue {};

Завдяки ключовим словом virtual буде включена лише одна копія підлеглого об'єкта Queue (див. Наступний малюнок).

Імітація об'єкта Lunch-Line з віртуальними базовими класами

Клас може мати як віртуальний, так і невіртуальний компонент заданого типу. Це відбувається за умов, які ілюструє наступний малюнок.

Віртуальні і невіртуальні компоненти одного класу

Віртуальні і невіртуальні компоненти одного класу

На цьому малюнку показано, що класи CashierQueue і LunchQueue використовують Queue як віртуальний базовий клас. Однак TakeoutQueue визначає Queue в якості базового класу, а не віртуального базового класу. Тому в LunchTakeoutCashierQueue є два підлеглих об'єкта типу Queue: один з шляху успадкування, що включає LunchCashierQueue, а другий з шляху, що включає TakeoutQueue. Це показано на наступному малюнку.

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

Примітка

Спадкування від віртуальних базових класів дозволяє істотно скоротити обсяг даних в порівнянні з успадкуванням від невіртуальних классов.Однако воно може породити додаткові витрати на обробку.

Якщо похідний клас переопределяет віртуальну функцію, яку він успадковує від віртуального базового класу, і якщо конструктор або деструктор похідного базового класу викликає цю функцію за допомогою покажчика на віртуальний базовий клас, то компілятор може вставити додаткові приховані поля vtordisp в класи з віртуальними базовими класами. Параметр компілятора / vd0 відключає додавання прихованого члена зміщення конструктора або деструктора vtordisp. Параметр компілятора / vd1 (за замовчуванням) дозволяє додавати їх в міру необхідності. Додавання полів vtordisps слід відключати тільки в тому випадку, якщо точно відомо, що всі конструктори і деструктори класів викликають віртуальні функції віртуально.

Параметр компілятора / vd діє на весь модуль компіляції. Використовуйте директиву #pragma vtordisp, щоб відключити, а потім повторно включити додавання полів vtordisp для кожного класу окремо:

#pragma vtordisp (off) class GetReal: virtual public {...}; #pragma vtordisp (on)

посилання

Кілька базових класів

Провайдеры:
  • 08.09.2015

    Batyevka.NET предоставляет услуги доступа к сети Интернет на территории Соломенского района г. Киева.Наша миссия —... 
    Читать полностью

  • 08.09.2015
    IPNET

    Компания IPNET — это крупнейший оператор и технологический лидер на рынке телекоммуникаций Киева. Мы предоставляем... 
    Читать полностью

  • 08.09.2015
    Boryspil.Net

    Интернет-провайдер «Boryspil.net» начал свою работу в 2008 году и на данный момент является одним из крупнейших поставщиков... 
    Читать полностью

  • 08.09.2015
    4OKNET

    Наша компания работает в сфере телекоммуникационных услуг, а именно — предоставлении доступа в сеть интернет.Уже... 
    Читать полностью

  • 08.09.2015
    Телегруп

    ДП «Телегруп-Украина» – IT-компания с 15-летним опытом работы на рынке телекоммуникационных услуг, а также официальный... 
    Читать полностью

  • 08.09.2015
    Софтлинк

    Высокая скоростьМы являемся участником Украинского центра обмена трафиком (UA — IX) с включением 10 Гбит / сек... 
    Читать полностью