C++中如何定义不能被继承的类

来源:互联网 发布:miui msa是什么软件 编辑:程序博客网 时间:2024/06/06 11:46

学习过Java和c#的童鞋应该都知道,在Java中定义了关键字final表示一个类不能被继承,在C#中也有相同意义的关键字sealed表示一个类不能被继承,那仫在C++中呢?在C++11之前是没有的类似这样的关键字的,只能自己实现了。(在C++11中该关键字已经被加入到C++中,这个关键字的作用就是阻止类的进一步派生和虚函数的进一步重载)。
如何在C++中定义一个不能被继承的类呢?
想法一:私有构造函数来解决
我们都知道在C++中子类的构造函数会自动调用父类的构造函数,子类的析构函数也会自动调用父类的析构函数。如果想要一个类无法被继承,那仫这个类的构造函数和析构函数必须是私有的,但是这样又会出现新的问题?就是这个类的构造函数和析构函数是私有的,我们如何获取和删除这个类的实例化对象呢?共有的静态函数就可以解决这个问题。

class Base{public:    //编写静态函数来创建和释放类的实例化    static Base *GetSpace()    {        cout<<"GetSpace()"<<endl;        return new Base();    }    static void DeleteSpace(Base *del)    {        cout<<"DeleteSpace()"<<endl;        delete del;    }private:    //私有化构造和析构函数    Base()    {}    ~Base()    {}};int main(){    //静态成员函数没有隐含this指针参数,使用类型::作用域访问符直接调用静态成员函数    Base *b=Base::GetSpace();    Base::DeleteSpace(b);    system("pause");    return 0;}

私有构造函数和静态成员函数实现不能被继承的类
这样的实现会不会存在什仫问题呢?通过观察上面的代码我发现实例化一个对象只能使用new来实例,也就是说这个新创建的对象只能在堆上生成,这就存在一定的局限性。那仫如何解决呢?
想法二:利用虚拟继承的方法
同样是将父类的构造函数私有化,但是却定义了一个模板类型的友元,因为友元的特性:如果一个类是另一个类的友元,友元类的每个成员函数都是另一个类的友元函数,都可访问另一个类中的保护或私有数据成员。我们在子类中调用父类的构造和析构函数是不会出错的。
这种想法比方法一的想法好的一点就是:既可以在堆上实例化对象也可以在栈上实例化对象。

template<typename T>class Base{    friend T;  //定义友元,子类可以访问父类的私有成员对象private:    Base()    {        cout<<"Base()"<<endl;    }    ~Base()    {        cout<<"~Base()"<<endl;    }};//虚继承class Sub:virtual public Base<Sub>  {public:    Sub()    {        cout<<"Sub()"<<endl;    }    ~Sub()    {        cout<<"~Sub()"<<endl;    }};int main(){    Sub s1;   //可以在栈上开辟    Sub *s2=new Sub; //可以在堆上开辟    delete s2;    system("pause");    return 0;}

虚拟继承
如果此时对Sub进行继承并对继承Sub的类进行实例化的时候是无法编译通过的。因为Sub是虚拟继承,所以当调用Test的构造函数的时候,会跳过Sub而直接调用Base的构造函数,又因为Base的构造函数是私有的且Test并不是Base的友元所以是不能调用的。
所以Sub就是满足题意的不能被继承的类。

class Test:public Sub{public:    Test()    {        cout<<"Test()"<<endl;    }    ~Test()    {        cout<<"~Test()"<<endl;    }};

当然了在C++中定义不能被继承的类有许多其他的方法,在这里我就只介绍这两种啦!!!

原创粉丝点击