Другое

Виртуальный класс: это что такое, зачем нужно и где используется?

Lorem ipsum dolor

Термин «виртуальный класс» на сегодняшний день имеет два совершенно разных определения:

  • виртуальный класс — это место для онлайн-обучения, куда заходят «ученики» (необязательно школьники!) и получают какую-то обучающую информацию; такой вид классов получил сильное распространение с приходом коронавирусной инфекции и с массовым переходом людей в онлайн-жизнь;

  • виртуальный класс — это термин, принадлежащий программированию и выражающий специфическое обозначение класса, объект которого будет общим для применения другими дочерними классами.

О первом определении термина «виртуальный класс» мы поговорим в одной из следующих статей, а сегодня разберем, что такое виртуальный класс в программировании.

 

Виртуальный класс в программировании что это?

Виртуальный класс — это некий базовый объект в программировании. Он создается только один раз, а потом применяется другими объектами в дереве наследования. Определяется он словом «virtual». Основная цель создания виртуального класса — предотвратить появление нескольких «интерпретаций» такого класса при использовании множественного наследия. Виртуальный класс часто применяется в языке программирования С++.

На практике виртуальный класс решает так называемую «проблему ромба» или «алмазную проблему», которая доставляет много проблем, а ее диаграмма будет выглядеть так:

 

 В такой ситуации, когда вам нужно будет инициировать создание объекта класса «Moto», по умолчанию у вас будет 2 копии класса «PoweredAuto»: одна будет из «Jeep», а другая из «Vaz». Иногда две копии одного объекта из разных классов будут уместны, но в большинстве случаев потребуется, чтобы «Jeep» и «Vaz» использовали только одну копию «PoweredAuto». Чтобы достичь этого, нужно будет создать «виртуальный класс» при помощи слова «virtual». В нашем случае это будет выглядеть примерно так:

 class PoweredAuto

{

};

 class Jeep: virtual public PoweredAuto

{

};

 class Vaz: virtual public PoweredAuto

{

};

 class Moto: public Jeep, public Vaz

{

};

 

В этом случае, если мы будем создавать объект «Moto», в ответ мы получим только одну копию «PoweredAuto» в объекте «Moto», при этом сама копия будет применяться и «Jeep», и «Vaz». 

Однако может возникнуть вопрос: если «Jeep» и «Vaz» применяют общий класс «PoweredAuto», то кто отвечает за создание последнего? В этой ситуации за его создание будет отвечать «Moto», а точнее, конструктор «Moto». Получается, что классу «Moto» можно будет единственный раз вызвать напрямую конструктор, который не является его родительским. 

На практике это будет выглядеть так:

#include <iostream>

 class PoweredAuto

{

public:

    PoweredAuto(int motor)

    {

std::cout << "PoweredAuto: " << motor << '\n';

    }

};

 

// хочется отметить, что теперь PoweredAuto будет «виртуальным классом»

class Jeep: virtual public PoweredAuto 

{

public:

    Jeep(int jeep, int motor)

        // эта строчка необходима для создания объектов Jeep,

        // но в нашем случае попадает под игнорирование

        : PoweredAuto{ motor } 

    {

std::cout << "Jeep: " << jeep << '\n';

    }

};

 

// нужно отметить, что здесь «PoweredAuto» также будет «виртуальным базовым классом»

class Vaz: virtual public PoweredAuto

{

public:

    Vaz(int vaz, intmotor)

        // эта строчка необходима для создания объектов Vaz,

        // но в нашем случае также попадает под игнорирование

        : PoweredAuto{ motor } 

    {

std::cout << "Vaz: " << vaz << '\n';

    }

};

 

class Moto: public Jeep, public Vaz

{

public:

    Moto(int jeep, int vaz, int motor)

        : PoweredAuto{ motor }, // PoweredAuto создается здесь

        Jeep{ jeep, motor }, Vaz{ vaz, motor }

    {

    }

};

 

Как видно, PoweredAuto создается единственный раз. 

Нужно отметить несколько моментов по работе с виртуальным классом:

  1. Виртуальный класс всегда создают перед его невиртуальными «братьями».

  2. Посмотрите внимательнее на пример: конструктор «Jeep» и «Vaz» все еще вызывают «PoweredAuto», однако при создании «Moto» эти вызовы попадают под игнорирование, потому что за создание «PoweredAuto» в нашем случае отвечает «Moto», а не «Jeep» или «Vaz».

  3. Даже если «Moto» будет унаследован только от «Jeep», а «Jeep» был унаследован от «PoweredAuto», за создание «PoweredAuto» все равно будет отвечать «Moto».

 

Заключение

Мы показали самый простейший пример, по каким принципам реализуется виртуальный класс в С++. Однако «виртуальный класс» это очень объемная тема, которая требует глубокого изучения перед ее применением.

Схожие статьи

Что такое Middleware или функции связующего программного обеспечения
Другое

Что такое Middleware или функции связующего программного обеспечения

Модификатор в языке С: определение, виды, инструкция по применению
Другое

Модификатор в языке С: определение, виды, инструкция по применению

Как правильно посчитать количество единичных битов числа
Другое

Как правильно посчитать количество единичных битов числа

Машинное обучение в страховой компании: основные задачи
Другое

Машинное обучение в страховой компании: основные задачи