题目:用C++设计一个不能被继承的类。

分析:这是Adobe公司2007年校园招聘的最新笔试题。这道题除了考察应聘者的C++基本功底外,还能考察反应能力,是一道很好的题目。

在Java中定义了关键字final,被final修饰的类不能被继承。但在C++中没有final这个关键字,要实现这个要求还是需要花费一些精力。

首先想到的是在C++ 中,子类的构造函数会自动调用父类的构造函数。同样,子类的析构函数也会自动调用父类的析构函数。要想一个类不能被继承,我们只要把它的构造函数和析构函数都定义为私有函数。那么当一个类试图从它那继承的时候,必然会由于试图调用构造函数、析构函数而导致编译错误。

可是这个类的构造函数和析构函数都是私有函数了,我们怎样才能得到该类的实例呢?这难不倒我们,我们可以通过定义静态来创建和释放类的实例。基于这个思路,我们可以写出如下的代码:

///
// Define a class which can't be derived from
///
class FinalClass1
{
public:static FinalClass1* GetInstance(){return new FinalClass1;}static void DeleteInstance( FinalClass1* pInstance){delete pInstance;pInstance = 0;}private:FinalClass1() {}~FinalClass1() {}
};

这个类是不能被继承,但在总觉得它和一般的类有些不一样,使用起来也有点不方便。比如,我们只能得到位于堆上的实例,而得不到位于栈上实例。

能不能实现一个和一般类除了不能被继承之外其他用法都一样的类呢?办法总是有的,不过需要一些技巧。请看如下代码:

///
// Define a class which can't be derived from
///
template <typename T> class MakeFinal
{friend T;private:MakeFinal() {}~MakeFinal() {}
};class FinalClass2 : virtual public MakeFinal<FinalClass2>
{
public:FinalClass2() {}~FinalClass2() {}
};

这个类使用起来和一般的类没有区别,可以在栈上、也可以在堆上创建实例。尽管类MakeFinal<FinalClass2>的构造函数和析构函数都是私有的,但由于类FinalClass2是它的友元函数,因此在FinalClass2中调用MakeFinal<FinalClass2>的构造函数和析构函数都不会造成编译错误。

但当我们试图从FinalClass2继承一个类并创建它的实例时,却不同通过编译。

class Try : public FinalClass2
{
public:Try() {}~Try() {}
};Try temp;

由于类FinalClass2是从类MakeFinal<FinalClass2>虚继承过来的,在调用Try的构造函数的时候,会直接跳过FinalClass2而直接调用MakeFinal<FinalClass2>的构造函数。非常遗憾的是,Try不是MakeFinal<FinalClass2>的友元,因此不能调用其私有的构造函数。

基于上面的分析,试图从FinalClass2继承的类,一旦实例化,都会导致编译错误,因此是FinalClass2不能被继承。这就满足了我们设计要求。

本文已经收录到《剑指Offer——名企面试官精讲典型编程题》一书中,有改动,书中的分析讲解更加详细。欢迎关注。

博主何海涛对本博客文章享有版权。网络转载请注明出处http://zhedahht.blog.163.com/。整理出版物请和作者联系。

程序员面试题精选100题(32)-不能被继承的类[C/C++/C#]相关推荐

  1. 程序员面试题精选100题

    程序员面试题精选100题(01)-把二元查找树转变成排序的双向链表 题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表.要求不能创建任何新的结点,只调整指针的指向. 比如将二元查找树   ...

  2. 程序员面试题精选100题:41-50解题报告

    程序员面试题精选100题(41)-把数组排成最小的数[算法]   题目:输入一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最小的一个.例如输入数组{32,  321},则输出这两个能 ...

  3. [程序员面试题精选100题]13.第一个只出现一次的字符

    [题目] 在一个字符串中找到第一个只出现一次的字符.如输入abaccdeff,则输出b. [分析] [代码] /********************************* * 日期:2013- ...

  4. 程序员面试题精选100题(51)-顺时针打印矩阵

    // 程序员面试题精选100题(51)-顺时针打印矩阵.cpp : 定义控制台应用程序的入口点. //#include "stdafx.h" #include <iostre ...

  5. 程序员面试题精选100题:求从1到n的正数中1出现的次数

    // 程序员面试题精选100题(25):求从1到n的正数中1出现的次数 // 如 f(253) = (2!=0) * 100 + 2 * f(99) + (5!=0) * 10 + 5 * f(9) ...

  6. 程序员面试题精选100题:11-40解题报告

    程序员面试题精选100题(11)-求二元查找树的镜像[数据结构]   题目:输入一颗二元查找树,将该树转换为它的镜像,即在转换后的二元查找树中,左子树的结点都大于右子树的结点.用递归和循环两种方法完成 ...

  7. [程序员面试题精选100题]19.反转链表

    题目 输入一个链表的头结点,反转该链表,并返回反转后链表的头结点. 分析 假设经过若干操作,我们已经把结点 pre之前的指针调整完毕,这些结点的next指针都指向前面一个结点.现在我们遍历到结点cur ...

  8. 程序员面试题精选100题(03)-子数组的最大和[算法]

    题目:输入一个整形数组,数组里有正数也有负数.数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.求所有子数组的和的最大值.要求时间复杂度为O(n). 例如输入的数组为1, -2, 3, ...

  9. python程序员面试题精选100题_在Python程序员面试中被问的最多的10道题

    我们在为大家整Python程序员面试试题中,发现了一些被面试官问到的最多的一些问题,以下就是本篇内容: Python是个非常受欢迎的编程语言,随着近些年机器学习.云计算等技术的发展,Python的职位 ...

最新文章

  1. HashTab---Windows资源管理器的文件属性窗口中添加了一个叫做”文件校验”的标签...
  2. 4月25日 python学习总结 互斥锁 IPC通信 和 生产者消费者模型
  3. linux git 修改文件,关于linux:Git删除所有未修改的文件
  4. verilog中的综合与不可综合
  5. 【ZJOI2019】线段树【线段树上dp】【大讨论】
  6. c++ 正则表达式_Java入门 - 语言基础 - 18.正则表达式
  7. 图片服务 - thumbor可用的探测器
  8. mac android通知中心,少数派一周快读:iOS 8 输入法大比拼,升级 Mac 新系统的 6 项准备,如何保持 Android 通知栏整洁...
  9. 北京君正:君子爱财,取之补助
  10. Hadoop 序列化
  11. switch php 比大小,PHP 基础:比较、If、Switch
  12. 小程序正式发布后,打开白屏(已解决)
  13. 吉林大学计算机学院控制与应用实验室,2019计算机考研吉林大学国家物联网虚拟仿真实验教学中心简...
  14. 优秀的免版权图库软件推荐,软件内图片均可免费商用。
  15. Python实现24点游戏
  16. 关于module ‘keras.applications’ has no attribute ‘nasnet’/ ‘keras’ has no attribute ‘application’的解决方案
  17. android 加载gif 动画,GifView——Android显示GIF动画
  18. 彩色空间(Color Space)
  19. android 短视频编辑,短视频编辑制作大师
  20. LeetCode1079题:活字印刷——Python递归与迭代解法

热门文章

  1. 从来富贵险中求 为何低学历的人能成为亿万富翁
  2. 沪港通:利好出尽就是利空
  3. 实战并发编程 - 10Guarded Suspension模式在BlockingQueue源码中应用
  4. Vue2.x-01点击按钮弹出子Vue组件,遍历JSON展示数据
  5. Spring JDBC-事务方法嵌套调用解读
  6. Python 中文编码
  7. @Autowired和@Resouce的区别
  8. python menu实例_Python高级进阶#019 pyqt5菜单menu应用,新建多窗体
  9. mysql制作html静态网页6_将数据库中的所有内容生成html静态页面的代码
  10. 2021-05-20 Matlab实现傅里叶变换