Рубрики

Имитация финального класса в C ++

Всегда задавался вопросом, как вы можете создать класс в C ++, который не может быть унаследован. Языки программирования Java и C # имеют эту встроенную функцию. Вы можете использовать ключевое слово final в Java, запечатанное в C #, чтобы сделать класс не расширяемым.

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

В следующем коде мы делаем класс Final не наследуемым. Когда класс Derived пытается наследовать от него, мы получаем ошибку компиляции.

Для нашей цели используется дополнительный класс MakeFinal (конструктор по умолчанию — private). Конструктор Final может вызывать приватный конструктор MakeFinal, так как Final — друг MakeFinal .

Обратите внимание, что MakeFinal также является виртуальным базовым классом. Причина этого заключается в том, чтобы вызывать конструктор MakeFinal через конструктор Derived , а не Final (конструктор виртуального базового класса не вызывается классом, который наследует его, вместо этого конструктор вызывается конструктором конкретного класса ).

/ * Программа с ошибкой компиляции, демонстрирующая, что класс Final не может

   быть унаследованным * /

#include<iostream>

using namespace std;

  

class Final;  // Класс должен быть окончательным

  

class MakeFinal // используется для финального класса Final

{

private:

    MakeFinal() { cout << "MakFinal constructor" << endl; }

friend class Final;

};

  

class Final : virtual MakeFinal

{

public:

    Final() { cout << "Final constructor" << endl; }

};

  

class Derived : public Final // Ошибка компилятора

{

public:

    Derived() { cout << "Derived constructor" << endl; }

};

  

int main(int argc, char *argv[])

{

    Derived d;

    return 0;

}

Вывод: ошибка компилятора

  In constructor 'Derived::Derived()':
  error: 'MakeFinal::MakeFinal()' is private

В приведенном выше примере конструктор Derived напрямую вызывает конструктор MakeFinal , а конструктор MakeFinal является закрытым, поэтому мы получаем ошибку компиляции.

Вы можете создать объект класса Final, так как он является другом классом MakeFinal и имеет доступ к его конструктору. Например, следующая программа работает нормально.

/ * Программа без какой-либо ошибки компиляции, чтобы продемонстрировать, что экземпляры

   Финальный класс может быть создан * /

#include<iostream>

using namespace std;

  

class Final;

  

class MakeFinal

{

private:

    MakeFinal() { cout << "MakeFinal constructor" << endl; }

    friend class Final;

};

  

class Final : virtual MakeFinal

{

public:

    Final() { cout << "Final constructor" << endl; }

};

  

int main(int argc, char *argv[])

{

    Final f;

    return 0;

}

Вывод: компилируется и работает нормально

MakeFinal constructor
Final constructor

Эта статья составлена Gopal Gorthi и рецензирована командой GeeksforGeeks. Пожалуйста, пишите комментарии, если вы обнаружите что-то неправильное или вы хотите поделиться дополнительной информацией по обсуждаемой выше теме.

Рекомендуемые посты:

Имитация финального класса в C ++

0.00 (0%) 0 votes