C++中防止一个类被继承

来源:互联网 发布:信号发生器软件 编辑:程序博客网 时间:2024/05/04 16:28

一、思路

在C++的继承里面我们知道,子类的构造函数会调用父类的构造函数,子类的析构函数会调用父类的析构函数,因此我们便想办法禁止子类调用父类的构造函数和析构函数即可,因此提出了如下两种方法。

二、方法

①构造函数与析构函数设置为私有

我们把父类的构造函数和析构函数定义为私有成员,此时子类便不可调用父类的构造函数和析构函数,因此便达成了防止一个类被继承的目的,但是此时又出现一个问题,我们如何区构造一个类对象呢。
我们可以写一个共有的静态的函数来返回一个对象,这种方式和只能在堆上建立对象是一样的。

class Myclass{public:    static Myclass* NewNode()    {        return new Myclass();    }    static void DeleteNode(Myclass* _Myclass)    {        delete  _Myclass;    }private:    Myclass()    {}    ~Myclass()    {}};class Child :public Myclass{public:    Child()    {}    ~Child()    {}};

此时会出现如下错误:

这里写图片描述

②使用虚拟继承

当我们使用虚拟继承构造一个类的时候,这样就会使得一个类可以在堆上建立对象也可以在栈上建立对象,这样也避免了方法一中出现的无法在栈上建立对象了。

下面我们先来看下代码:

#include <iostream>using namespace std;template <class T>class Base{    friend T;//模板参数类型作为友元函数private:    Base()    {}    ~Base()    {}};//FinalClass作为Base的友元,可以访问Base的私有成员class MyClass:virtual public Base<MyClass>{public:    MyClass()    {}    ~MyClass()    {}};//TestClass继承于Base类//由于是虚拟继承,派生类会访问基类的构造函数和析构函数//但是由于基类的构造函数是私有所以无法访问class TestClass: public MyClass{public:    TestClass()    {}//这里会报错    ~TestClass()    {}//这里会报错};int main(){    MyClass *p = new MyClass;    MyClass fc;    TestClass tc;    return 0;}

分析:

下面我们来看下我们缩写的MyClass类,由于它虚拟继承于Base类,同时作为Base的友元,此时可以访问Base的私有的构造函数和析构函数。

因此它可以在堆上建立对象,也可以在栈上建立对象。

那么它能否被继承呢,我便写了一个TestClass的类去继承它,编译器报错了。

因为在构造对象的时候,由于MyClass是虚拟继承,派生类会直接访问基类也就是Base类的构造函数和析构函数,而Base类里面的构造函数和析构函数是私有的,所以无法继承。