32.C++不能被继承的类[C++ Final Class]
【题目】
用C++设计一个不能被继承的类。
【分析】
这是Adobe公司2007年校园招聘的最新笔试题。这道题除了考察应聘者的C++基本功底外,还能考察反应能力,是一道很好的题目。
在Java中定义了关键字final,被final修饰的类不能被继承。但在C++中没有final这个关键字,要实现这个要求还是需要花费一些精力。
首先想到的是在C++ 中,子类的构造函数会自动调用父类的构造函数。同样,子类的析构函数也会自动调用父类的析构函数。要想一个类不能被继承,我们只要把它的构造函数和析构函数都定义为私有函数。那么当一个类试图从它那继承的时候,必然会由于试图调用构造函数、析构函数而导致编译错误。
可是这个类的构造函数和析构函数都是私有函数了,我们怎样才能得到该类的实例呢?这难不倒我们,我们可以通过定义静态来创建和释放类的实例。基于这个思路,我们可以写出如下的代码:
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
///////////////////////////////////////////////////////////////////////
// Define a class which can't be derived from /////////////////////////////////////////////////////////////////////// class FinalClass1 { public: static FinalClass1 *GetInstance() { return new FinalClass1; } static void DeleteInstance( FinalClass1 *pInstance) private: |
这个类是不能被继承,但在总觉得它和一般的类有些不一样,使用起来也有点不方便。比如,我们只能得到位于堆上的实例,而得不到位于栈上实例。能不能实现一个和一般类除了不能被继承之外其他用法都一样的类呢?办法总是有的,不过需要一些技巧。请看如下代码:
【代码】
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
template <typename T>
class Base { friend T; private: Base() {} ~Base() {} }; class FinalClass: virtual public Base<FinalClass> class NewClass: public FinalClass int _tmain(int argc, _TCHAR *argv[]) //NewClass nc; // ERROR! ; |
现在看看我们的Finalclass类,继承于Base,Base为虚基类。因为它是Base的友元,所以它可以访问基类的私有构造函数,以及析构函数。编译运行时是正确的。也就是说,可以创建堆上的对象,并且可以构建栈上的对象。
可否继承?假如它作为一个基类被一个类继承,在编译时是完全可以通过的。这一点没有什么疑问,问题就出在运行时:当子类在构造对象时,因为是虚继承,所以子类的构造函数会直接去调用Base类的构造函数,而Base的构造函数是私有的,运行错误error!!!
这就是一个真正不能被继承的类。
【参考】
http://zhedahht.blog.163.com/blog/static/25411174200793181548842/
http://www.cnblogs.com/Braveliu/archive/2013/01/03/2842739.html
http://blog.csdn.net/lazy_tiger/article/details/2224899
32.C++不能被继承的类[C++ Final Class]的更多相关文章
- 用C++设计一个不能被继承的类(转)
在Java 中定义了关键字final,被final修饰的类不能被继承. 首先想到的是在C++中,子类的构造函数会自动调用父类的构造函数.同样,子类的析构函数也会自动调用父类的析构函数.要想一个类不能被 ...
- C++实现不能被继承的类——终结类 分类: C/C++ 2015-04-06 14:48 64人阅读 评论(0) 收藏
1. 问题 C++如何实现不能被继承的类,即终结类.Java中有final关键字修饰,C#中有sealed关键字修饰,而C++目前还没有类似的关键字来修饰类实现终结类,需编程人员手动实现. ...
- 用C++设计一个不能被继承的类(用私有构造函数+友元函数)
题目:用C++设计一个不能被继承的类. 分析:这是Adobe公司2007年校园招聘的最新笔试题.这道题除了考察应聘者的C++基本功底外,还能考察反应能力,是一道很好的题目. 在Java中定义了关键字f ...
- final类与final方法
inal---用于类.方法前. final类---不可被继承. final方法---不可被覆盖. final类不能被继承. 如果我们不希望一个类被继承,我们使用final来修饰这个类.这个类将无法被继 ...
- c++设计一个无法被继承的类
要求是该类不能被继承,但是能够像正常的类一样使用.那么一下方法就不符合题目要求: 1.构造函数和析构函数设置为private.这样就不能定义一个类的实例 2.类似于singleton模式那样,定义一个 ...
- C++设计实现一个不能被继承的类
C++不同于Java,Java中被final关键字修饰的类不能被继承,C++能实现不被继承的类,但是需要自己实现. 为了使类不被继承,最好的办法是使子类不能构造父类的部分,此时子类就无法实例化整个子类 ...
- Final类和Final方法
终止继承 Final类 当关键字final用来修饰类时,其含义是该类不能在派生子类.换句话说,任何其他类都不能继承用final修饰的类,即使该类的访问限制为public类型,也不能被继承:否则,将编译 ...
- PHP 面向对象 final类与final方法
final---用于类.方法前. final类---不可被继承. final方法---不可被覆盖. final类不能被继承. 如果我们不希望一个类被继承,我们使用final来修饰这个类.这个类将无法被 ...
- 探讨C++实现一个不可被继承的类
C#和Java都提供了一种机制让一个类不能被继承,如C#中的sealed关键字和Java的final关键字,然而C++程序员就没这么好命了.不过C++也可以模拟出这种效果,原理基于:子类的构造函数会自 ...
随机推荐
- html5_canvas-记忆力卡片游戏
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Mysql-日期转换
一.字符串转日期 下面将讲述如何在MYSQL中把一个字符串转换成日期: 背景:rq字段信息为:20100901 1.无需转换的: SELECT * FROM tairlist_day WHERE rq ...
- BZOJ1113 海报PLA
好像是很古老的题?现在BZOJ上找不到该题,所以没有提交. 1113: [Poi2008]海报PLA Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 8 ...
- Xcon2014 && Geekpwn2014
目录 . 链接器与加载器技术在保护壳上的应用 . android应用市场中的大规模漏洞挖掘 . android模拟躲避检测和应对 . 内核链表的奥秘 . 信号的可发现性 -- wifi之外我们还能做什 ...
- jquery中datagrid中getSelected和getSelections的应用
http://blog.sina.com.cn/s/blog_8e50ede90101fff9.html 刚开始使用jquery的datagrid就知道如果要对特定的一行进行编辑,可以是 $('#on ...
- [Angularjs]视图和路由(二)
写在前面 上篇文章主要介绍了视图和路由的基本概念,并在文章最后举了一个简单的使用案例.这篇文章将继续学习路由的配置,及相关参数的说明. 系列文章 [Angularjs]ng-select和ng-opt ...
- PHP利用Filesystem函数实现操作缓存(生成,获取,删除操作)
<?php class File{ //$key 相当于缓存文件的文件名 //$value 缓存数据 private $_dir;//定义默认路径 const EXT='.txt'; publi ...
- 创建泛类集合List以及数组转集合,集合转数组的应用
List<int> list = new List<int>(); list.Add(); list.Add(); list.Add(); list.AddRange(, , ...
- Ward BRDF实现心得
最近做了Ward BRDF的实现,相对于之前的lambert,phong来说,Ward是一个真正意义上的各向异性BRDF,但同样的,Ward模型也是一个基于经验的模型,并不是物理上正确的.它由ward ...
- jquery设置和获得checkbox选中问题
1.设置checkbox选中: //选中多选框 checkbox=$("#agentinfo input[name='veri[]']"); //循环多选框中的值 checkbox ...