【题目】

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

【分析】

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

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

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

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

 C++ Code 
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)
    {
        delete pInstance;
        pInstance = ;
    }

private:
    FinalClass1() {}
    ~FinalClass1() {}
};

这个类是不能被继承,但在总觉得它和一般的类有些不一样,使用起来也有点不方便。比如,我们只能得到位于堆上的实例,而得不到位于栈上实例。能不能实现一个和一般类除了不能被继承之外其他用法都一样的类呢?办法总是有的,不过需要一些技巧。请看如下代码:

【代码】

 C++ Code 
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>
{
public:
    FinalClass() {}
    ~FinalClass() {}
};

class NewClass: public FinalClass
{
    // can pass at compiler time,but can not pass at runtime.
};

int _tmain(int argc, _TCHAR *argv[])
{
    FinalClass fc;
    FinalClass *fcnew = new FinalClass();
    delete fcnew;

//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]的更多相关文章

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

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

  2. C++实现不能被继承的类——终结类 分类: C/C++ 2015-04-06 14:48 64人阅读 评论(0) 收藏

    1.       问题 C++如何实现不能被继承的类,即终结类.Java中有final关键字修饰,C#中有sealed关键字修饰,而C++目前还没有类似的关键字来修饰类实现终结类,需编程人员手动实现. ...

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

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

  4. final类与final方法

    inal---用于类.方法前. final类---不可被继承. final方法---不可被覆盖. final类不能被继承. 如果我们不希望一个类被继承,我们使用final来修饰这个类.这个类将无法被继 ...

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

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

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

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

  7. Final类和Final方法

    终止继承 Final类 当关键字final用来修饰类时,其含义是该类不能在派生子类.换句话说,任何其他类都不能继承用final修饰的类,即使该类的访问限制为public类型,也不能被继承:否则,将编译 ...

  8. PHP 面向对象 final类与final方法

    final---用于类.方法前. final类---不可被继承. final方法---不可被覆盖. final类不能被继承. 如果我们不希望一个类被继承,我们使用final来修饰这个类.这个类将无法被 ...

  9. 探讨C++实现一个不可被继承的类

    C#和Java都提供了一种机制让一个类不能被继承,如C#中的sealed关键字和Java的final关键字,然而C++程序员就没这么好命了.不过C++也可以模拟出这种效果,原理基于:子类的构造函数会自 ...

随机推荐

  1. angular自己的笔记

    angular知道怎么用了, 就打算读一读源代码; <html ng-app="phonecatApp"> <head> <meta charset= ...

  2. hdu3986 spfa+枚举

    这题让我第一次感受到了什么叫做在绝望中A题.这题我总共交了18次,TLE不知道几次,WA也不知道几次. 这题不能用dijkstra,用这个我一直超时(我没试过dij+优先队列优化,好像优先队列优化后可 ...

  3. C 文件读写2

    feof() int  feof(FILE *stream); 在执行读文件操作时,如果遇到文件尾,则函数返回逻辑真(1):否则,则返回逻辑假(0). feof()函数同时适用于ASCII码文件和二进 ...

  4. 【HDU 5115】Dire Wolf

    题意 n只狼排成一行,每次击败第i只狼需要ai+bi-1+bi+1代价,击败后,相当于出列了,与i相邻两只狼成了相邻的.求击败所有狼的最小总代价. 分析 我开始一直以为是个环TAT.. 区间dp,dp ...

  5. 【CodeForces 312B】BUPT 2015 newbie practice #3A Archer

    题 SmallR is an archer. SmallR is taking a match of archer with Zanoes. They try to shoot in the targ ...

  6. Oracle查看锁表

     查看锁表进程SQL语句1: select sess.sid,     sess.serial#,     lo.oracle_username,     lo.os_user_name,     a ...

  7. NOI题库

    07:机器翻译 总时间限制: 1000ms 内存限制: 65536kB 描述 小晨的电脑上安装了一个机器翻译软件,他经常用这个软件来翻译英语文章. 这个翻译软件的原理很简单,它只是从头到尾,依次将每个 ...

  8. appium-向右滑动定位

    上面5幅欢迎图,要向右滑动4次再点击[立即体验]才可以到首屏 #首页欢迎图滑动4次 for i in range(4): driver.swipe(1200, 200, 10, 200, 1500) ...

  9. ubuntu 12.04 server + OPENACS(TR069)安装配置日记

    1. 有两个叫openacs的, openacs.org下的不是 2. 严格匹配版本:luo@bogon:~$ ls jboss-4.2.3.GA-jdk6.zip  jdk-6u41-linux-i ...

  10. leach协议matlab仿真代码

    http://www.ilovematlab.cn/thread-177006-1-1.html LEACH協議clear;%清除內存變量 xm=100;%x軸範圍ym=100;%y軸範圍 sink. ...