📜  在C++中模拟最终课程

📅  最后修改于: 2021-05-30 06:26:24             🧑  作者: Mango

曾经想过如何在C++中设计一个无法继承的类。 Java和C#编程语言具有内置的此功能。您可以在Java使用final关键字(使用C#密封)使类不可扩展。
下面是一种机制,利用该机制我们可以在C++中实现相同的行为。它利用了私有构造函数,虚拟继承和朋友类。
在以下代码中,我们使Final类成为不可继承的。当派生类尝试从其继承时,我们会收到编译错误。
一个额外的类MakeFinal (其默认构造函数为private)用于我们的目的。 Final的构造函数可以调用MakeFinal的私有构造函数,因为FinalMakeFinal的朋友。
请注意, MakeFinal还是虚拟基类。这样做的原因是通过Derived的构造函数而不是Final来调用MakeFinal的构造函数(从其继承的类不调用虚拟基类的构造函数,而是由具体类的构造函数调用该构造函数)。

由于在C++ 11中支持 最终说明符,第三个示例显示了其实现。

c
/* A program with compilation error to demonstrate that Final class cannot
   be inherited */
#include
using namespace std;
 
class Final;  // The class to be made final
 
class MakeFinal // used to make the Final class final
{
private:
    MakeFinal() { cout << "MakFinal constructor" << endl; }
friend class Final;
};
 
class Final : virtual MakeFinal
{
public:
    Final() { cout << "Final constructor" << endl; }
};
 
class Derived : public Final // Compiler error
{
public:
    Derived() { cout << "Derived constructor" << endl; }
};
 
int main(int argc, char *argv[])
{
    Derived d;
    return 0;
}


C
/* A program without any compilation error to demonstrate that instances of
   the Final class can be created */
#include
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;
}


C++
#include 
using namespace std;
 
class Base final {
    // body
};
class Derived : public Base // compile error because base class is final
{
    // body
};
 
int main() { return 0; }


输出:编译器错误

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

在上面的例子中,派生类的构造函数调用直接MakeFinal的构造,和MakeFinal的构造函数是私有的,因此我们得到的编译错误。
您可以创建Final类的对象,因为它是MakeFinal的朋友类,并且可以访问其构造函数。例如,以下程序可以正常运行。

C

/* A program without any compilation error to demonstrate that instances of
   the Final class can be created */
#include
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

C++ 11更新:-

在C++ 11中,我们可以使用final指定符使基类不可继承。例如,以下代码在将基类声明为final时给出了编译错误。

C++

#include 
using namespace std;
 
class Base final {
    // body
};
class Derived : public Base // compile error because base class is final
{
    // body
};
 
int main() { return 0; }

输出:

prog.cpp:8:7: error: cannot derive from ‘final’ base ‘base’ in derived type ‘derive’
 class derive: public base  // compile error because base class is final
要从最佳影片策划和实践问题去学习,检查了C++基础课程为基础,以先进的C++和C++ STL课程基础加上STL。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程”