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的私有构造函数.故而编译错误.

探讨C++实现一个不可被继承的类的更多相关文章

  1. 用C++设计一个不能被继承的类(用私有构造函数+友元函数)

    题目:用C++设计一个不能被继承的类. 分析:这是Adobe公司2007年校园招聘的最新笔试题.这道题除了考察应聘者的C++基本功底外,还能考察反应能力,是一道很好的题目. 在Java中定义了关键字f ...

  2. 用C++设计一个不能被继承的类(转)

    在Java 中定义了关键字final,被final修饰的类不能被继承. 首先想到的是在C++中,子类的构造函数会自动调用父类的构造函数.同样,子类的析构函数也会自动调用父类的析构函数.要想一个类不能被 ...

  3. 用C++实现一个不能被继承的类

    #include<iostream> using namespace std; class Gradpa { friend class Parent;//声明public或者private ...

  4. C++设计实现一个不能被继承的类

    C++不同于Java,Java中被final关键字修饰的类不能被继承,C++能实现不被继承的类,但是需要自己实现. 为了使类不被继承,最好的办法是使子类不能构造父类的部分,此时子类就无法实例化整个子类 ...

  5. 面试题48:用C++设计一个不能被继承的类

    解法一:把构造函数设为私有 将构造函数定义为私有,然后通过定义公有的静态函数来创建和释放类的实例. { public: static SealedClass1* GetInstance() { ret ...

  6. 用C++ 设计一个不能被继承的类

    http://blog.sina.com.cn/s/blog_69d9bff30100odlz.html 在Java 中定义了关键字final ,被final 修饰的类不能被继承.但在C++ 中没有f ...

  7. 用c++编写一个不能被继承的类(但是可以在类外部定义该类的对象)

    据我们知道,我们只要把类的构造函数和析构函数定义为private类型,那么就不能够在外部建立给类的对象,也就不能以给类为基类进行继承,因为如果继承,建立对象的时候将要调用基类的构造函数,但是因为为pr ...

  8. c++设计一个无法被继承的类

    要求是该类不能被继承,但是能够像正常的类一样使用.那么一下方法就不符合题目要求: 1.构造函数和析构函数设置为private.这样就不能定义一个类的实例 2.类似于singleton模式那样,定义一个 ...

  9. C++设计一个不能被继承的类

    1. 方法一 将构造函数和析构函数设置为私有函数,重新定义公有的静态函数来创建和释放类. #include "stdafx.h" #include <iostream> ...

随机推荐

  1. C语言学习记录_2019.02.04

    逻辑性变量的定义符:bool,在C语言中只有true和false: 定义方式:bool t = true; 逻辑运算符: !:逻辑非 &&:逻辑与 ||:逻辑或 表达区间的错误形式:4 ...

  2. 转载:隐藏bat窗口在后台运行(找了好久)

    https://mp.weixin.qq.com/s?__biz=MzU4MjY1ODA3Nw==&mid=2247484277&idx=1&sn=8b5d98aab3827b ...

  3. linux普通用户su root切换提示没有文件或目录

    1. 首先进入单用户模式: 1). ubuntu : 上述情况可以在grub界面选择第二项修复,但没有grub可以参考: 1.重启ubuntu,随即长按shirft进入grub菜单: 2.选择reco ...

  4. 9-客户端集成IdentityServer

    1-创建客户端的webapi项目 E:\coding\netcore\IdentityServerSample>dotnet new webapi --name IdentityCredenti ...

  5. OracleLinux上安装数据库(DBCA)

    磨砺技术珠矶,践行数据之道,追求卓越价值 回到上一级页面: PostgreSQL杂记页     回到顶级页面:PostgreSQL索引页 [作者 高健@博客园  luckyjackgao@gmail. ...

  6. 优步UBER司机全国各地奖励政策汇总 (2月22日-2月28日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  7. 模拟实现MyBatis中通过SQL反射实体类对象功能

    话不多说,直接上干货! package cn.test; import java.lang.reflect.Method; import java.sql.Connection; import jav ...

  8. HTMLTestRunner.py(Python3)

    """A TestRunner for use with the Python unit testing framework. Itgenerates a HTML re ...

  9. Pycharm中查看方法的源码

    方法1.鼠标放在函数上,Ctrl+B,看源码 方法2.将光标移动至要查看的方法处,按住ctrl 键,点击鼠标左键,即可查看该方法的源码.

  10. TPO-14 C1 Locate a political book

    TPO-14 C1 Locate a political book 第 1 段 1.Listen to a conversation between the student and librarian ...