zoukankan      html  css  js  c++  java
  • C++实现不能被继承的类——终结类 分类: C/C++ 2015-04-06 14:48 64人阅读 评论(0) 收藏

    1.       问题

        C++如何实现不能被继承的类,即终结类。Java中有final关键字修饰,C#中有sealed关键字修饰,而C++目前还没有类似的关键字来修饰类实现终结类,需编程人员手动实现。

     

    2.       解决方法

        基本思路:由于任何派生类的对象在创建的时候,都必需在派生类的构造函数中调用父类的构造函数。所以,只要类的构造函数在子类中无法被访问,那么就阻止了该类被继承,实现终结类。

        如果将一个类的构造函数声明为私有(private),可以阻止该类进一步派生,但是该类也无法直接实例化了,此方法行不通。注意,构造函数为private的类,无法直接实例化,但是可以被间接实例化。间接实例化方法是:类中定义一个公有的静态成员函数,由这个函数来完成对象的初始化工作。联想到C++的单例模式singleton,也是用到了这个方法,C++的单例模式的实现见如下代码:

    class CSingleton  
    {  
    private:  
        CSingleton(){};   //构造函数是私有的  
        static CSingleton *m_pInstance;  
    public:  
        static CSingleton * GetInstance()  
        {  
            if(m_pInstance == NULL)  //判断是否第一次调用  
                m_pInstance = new CSingleton();  
            return m_pInstance;  
        }  
    };  
    
        C++中实现不能被继承的类的最为有效安全方便的方法是使用“虚拟继承”。一个基类如果被虚拟继承,那么在创建它的孙子类的对象时,该基类的构造函数需要单独被调用。此时,如果该基类的构造函数在孙子类的构造函数中无法访问,那么就实现了基类的子类不能被继承。

        利用虚拟继承的这种特性,我们可以设计出这样一个基类FinalParent,它不定义任何数据成员,这样任何类从它派生并不会增加任何空间上的开销。将它的默认构造函数的访问权限设定为protected,这样它自身不能产生任何实例,只能用作基类。一个使用基类FinalParent的实现终结类的例子如下:

    #include <iostream>
    using namespace std;
    class FinalParent
    {
    protected:
      FinalParent();
    };
    
    class FinalClass:private virtual FinalParent
    {
    public:
      FinalClass():num(1){};
      void show()
      {
         cout<<"num:"<<num<<endl;
      }
    private:
      int num;
    
    };
    
    class FinalClassChild:public FinalClass
    {
      int a;
    public:
      FinalClassChild():a(0){};
    };
    
    int main(int argc,char* argv[])
    {
      FinalClassChild f;//报错,无法访问FinalParent::FinalParent()
      return 0;
    }
    
        从程序中可以看出,当FinalClassChild试图继承FinalClass的时候,FinalClassChild的构造函数中需要调用FinalParent的构造函数,而FinalParent的构造函数在FinalClass中已经变成了私有private,不能被FinalClassChild的任何成员函数所访问,导致编译错误。所以,任何一个类,只要虚拟继承类FinalParent,就不能被继续继承,从而简单、高效安全的实现了“终结类”。

    参考文献:

    [1]陈刚.C++高级进阶教程[M].武汉:武汉大学出版社,2008:280-282







    版权声明:本文为博主原创文章,未经博主允许不得转载。

    ---转载或者使用代码,请注明原作者 This is bill
  • 相关阅读:
    Windows Console 程序中定时器的使用
    AT91SAM7SE应用 IRQ
    AT91SAM7SE应用 PIT 周期中断(1ms)
    AT91SAM7SE应用 UART
    Modelsim图像处理算法的仿真——图像数据操作
    按照一定的间隔,从视频中截图并保存(OpenCV)
    MacBook Pro下关闭全局网络代理
    jmeter的HTTP取样器设置重连的次数
    【C#】比较 Random 与 RandomNumberGenerator 生成随机字符串
    KendoGrid基础
  • 原文地址:https://www.cnblogs.com/ScytheWH/p/4622980.html
Copyright © 2011-2022 走看看