探讨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派生:
{
public:
CSomeDerive(){}
~CSomeDerive(){}
};
CSomeDerive的构造函数调用过程如下:由于CFobidDeriveProvider是从CFobidDeriveProviderBase虚拟派生,在虚继承出现的继承层次中,总是在构造非虚基类之前构造虚基类,因而会跳过CNoDerive和CFobidDeriveProvider的构造函数而直接调用CFobidDeriveProviderBase的构造函数,但CSomeDerive不是CFobidDeriveProviderBase的友元,因此也无法调用CFobidDeriveProviderBase的私有构造函数.故而编译错误.
探讨C++实现一个不可被继承的类的更多相关文章
- 用C++设计一个不能被继承的类(用私有构造函数+友元函数)
题目:用C++设计一个不能被继承的类. 分析:这是Adobe公司2007年校园招聘的最新笔试题.这道题除了考察应聘者的C++基本功底外,还能考察反应能力,是一道很好的题目. 在Java中定义了关键字f ...
- 用C++设计一个不能被继承的类(转)
在Java 中定义了关键字final,被final修饰的类不能被继承. 首先想到的是在C++中,子类的构造函数会自动调用父类的构造函数.同样,子类的析构函数也会自动调用父类的析构函数.要想一个类不能被 ...
- 用C++实现一个不能被继承的类
#include<iostream> using namespace std; class Gradpa { friend class Parent;//声明public或者private ...
- C++设计实现一个不能被继承的类
C++不同于Java,Java中被final关键字修饰的类不能被继承,C++能实现不被继承的类,但是需要自己实现. 为了使类不被继承,最好的办法是使子类不能构造父类的部分,此时子类就无法实例化整个子类 ...
- 面试题48:用C++设计一个不能被继承的类
解法一:把构造函数设为私有 将构造函数定义为私有,然后通过定义公有的静态函数来创建和释放类的实例. { public: static SealedClass1* GetInstance() { ret ...
- 用C++ 设计一个不能被继承的类
http://blog.sina.com.cn/s/blog_69d9bff30100odlz.html 在Java 中定义了关键字final ,被final 修饰的类不能被继承.但在C++ 中没有f ...
- 用c++编写一个不能被继承的类(但是可以在类外部定义该类的对象)
据我们知道,我们只要把类的构造函数和析构函数定义为private类型,那么就不能够在外部建立给类的对象,也就不能以给类为基类进行继承,因为如果继承,建立对象的时候将要调用基类的构造函数,但是因为为pr ...
- c++设计一个无法被继承的类
要求是该类不能被继承,但是能够像正常的类一样使用.那么一下方法就不符合题目要求: 1.构造函数和析构函数设置为private.这样就不能定义一个类的实例 2.类似于singleton模式那样,定义一个 ...
- C++设计一个不能被继承的类
1. 方法一 将构造函数和析构函数设置为私有函数,重新定义公有的静态函数来创建和释放类. #include "stdafx.h" #include <iostream> ...
随机推荐
- Git使用规范(三)
今天我们来介绍一下Git的一些操作,这个里面主要是一些我们平时遇到的一些问题 1.当我进入了一个分支的是时候,我在查看git log的时候,为什么会有别人的信息,我一直以为 这个是查看分支提交情况, ...
- 注册COM组件cmd(管理员权限)
比如,注册这个很老版本的office组件 C:\Windows\system32>regsvr32 d:\dsoframer.ocx
- 【LG1527】[国家集训队]矩阵乘法
[LG1527][国家集训队]矩阵乘法 题面 洛谷 题解 我也不知道为什么取个这样的名字... 其实就是区间\(kth\)扩展到二维 还是用整体二分搞啦,把树状数组换成二维的 其他的基本没有什么差别 ...
- P1094 纪念品分组
P1094 纪念品分组 题目描述 元旦快到了,校学生会让乐乐负责新年晚会的纪念品发放工作.为使得参加晚会的同学所获得 的纪念品价值相对均衡,他要把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪 ...
- mysql 题目练习
1 新建一个测试数据库: create database test1 charset utf8; 2 进入数据库 use test1; 3 新建一个sql 文件 ,将下面内容复制进sql 文件 /* ...
- 相机-imu外参校准总结
1. 研究背景及相关工作 1)研究背景 单目视觉惯性slam是一种旨在跟踪移动平台的增量运动并使用来自单个车载摄像头和imu传感器的测量结果同时构建周围环境地图的技术.视觉相机和惯性测量单元(imu) ...
- python 解决url编译
from urllib import parse s = parse.unquote("%7B%22name%22%3A%22joe%22%2C%22age%22%3A%2223%22%7D ...
- dva webpack 利用require.context加载多个model
dva redux数据管理都在models,根据业务不同models可能会有几十甚至上百的 [模块.js], 每次在index.js使用 app.model(require('./models/exa ...
- 使用.net 更新word目录
方案一.采用OpenXml(服务器不依赖Office组件) 在word生成的最后加上代码: using (WordprocessingDocument docx = WordprocessingDoc ...
- Siki_Unity_0_Unity A计划直播视频
Unity A计划直播视频 2017-07-04直播 任务1:如何识别以招聘来招培训生的公司: 打着招聘的旗号帮培训机构找培训生 关键词:实训生 任务2:如何识别一个公司的好坏和规模大小: 猎聘(中高 ...