Другое

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

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».

 

Заключение

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

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

SHA1 расшифровка: что это, как использовать шифрование, алгоритм SHA3
Другое

SHA1 расшифровка: что это, как использовать шифрование, алгоритм SHA3

Опера для разработчиков. Подробный обзор инструментов для разработки
Другое

Опера для разработчиков. Подробный обзор инструментов для разработки

Какие вопросы можно и нужно задать на собеседовании работодателю?
Другое

Какие вопросы можно и нужно задать на собеседовании работодателю?

Другое

Каковы преимущества и недостатки Windows?

×