zoukankan      html  css  js  c++  java
  • 探讨C++实现一个不可被继承的类

    C#和Java都提供了一种机制让一个类不能被继承,如C#中的sealed关键字和Java的final关键字,然而C++程序员就没这么好命了.不过C++也可以模拟出这种效果,原理基于:子类的构造函数会自动调用父类的构造函数,同理析构函数也是一样.如果父类的构造函数和析构函数被设为私有的话,那么子类就无法调用,也就达到了父类不可被继承的目的了。原理很简单,按此原理我也实作出一个自认为很实用的工具类,在此献下丑,欢迎大家批评:
    template< typename TDerive, typename TProvider >
    class  CFobidDeriveProviderBase
    {
        friend TDerive;
        friend TProvider;
        
    private:
        CFobidDeriveProviderBase(){}
        
    ~CFobidDeriveProviderBase(){}
    };

    /*
    * 提供禁止派生的功能,需要此功能的类可以从CFobidDeriveProvider派生,并将类名作为模板参数传递
    */
    template
    < typename TDerive >
    class  CFobidDeriveProvider : virtual public CFobidDeriveProviderBase< TDerive, CFobidDeriveProvider<TDerive>>
    {
    public:
        CFobidDeriveProvider(){}
        
    ~CFobidDeriveProvider(){}
    };

    /*
    * 测试类,该类不可被继承
    */
    class  CNoDerive : public CFobidDeriveProvider< CNoDerive >
    {
    public:
        CNoDerive(){}
        
    ~CNoDerive(){}

        
    void  Alert()
        {
            AtlMessageBox( NULL, _T(
    "Alert") );
        }
    };

    之所以将继承的结构分为2层:CFobidDeriveProvider和CFobidDeriveProviderBase,主要是方便使用,用户只需直接从CFobidDeriveProvider派生就可实现一个不可被继承的类,而不需要虚拟继承。

    若有类从CNoDerive派生:

    class  CSomeDerive : public CNoDerive
    {
    public:
        CSomeDerive(){}
        
    ~CSomeDerive(){}
    };
    CSomeDerive的构造函数调用过程如下:由于CFobidDeriveProvider是从CFobidDeriveProviderBase虚拟派生,在虚继承出现的继承层次中,总是在构造非虚基类之前构造虚基类,因而会跳过CNoDerive和CFobidDeriveProvider的构造函数而直接调用CFobidDeriveProviderBase的构造函数,但CSomeDerive不是CFobidDeriveProviderBase的友元,因此也无法调用CFobidDeriveProviderBase的私有构造函数.故而编译错误.
  • 相关阅读:
    CMake基本语法
    Immutable使用与react+redux
    mysql 安装之docker
    elasticsearch 安装之docker 单机
    局域网共享时提示:你没有权限访问,请与网络管理员联系
    【python、Neo4j】 python3.6环境安装neo4j客户端
    【python】 Anaconda jupyter 服务正常,内核启动失败, ipython启动失败
    Neo4j 手动安装apoc插件
    Ubuntu16 安装配置Neo4j
    node工具之nodemon
  • 原文地址:https://www.cnblogs.com/fangkm/p/1442117.html
Copyright © 2011-2022 走看看