http://blog.sina.com.cn/s/blog_69d9bff30100odlz.html

在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 不能被继承。这就满足了我们设计要求。

用C++ 设计一个不能被继承的类的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. ASP 生成带日期的随机数

    <% Function getRnd() '**************************************** '返回值:如getRnd(),即输出2008082415534646 ...

  2. Android入门开发之销毁activity

    使用: 销毁.关闭页面activity 如果打开下个页面的同时销毁了本页面,在下个页面无法返回本页面,每次打开APP应用就会先显示一张APP的介绍图.或者LOGO页面,延时几秒进入应用,进入后无法再返 ...

  3. Apache Rewrite url重定向功能的简单配置

    http://www.jb51.net/article/24435.htm 1.Apache Rewrite的主要功能 就是实现URL的跳转和隐藏真实地址,基于Perl语言的正则表达式规范.平时帮助我 ...

  4. ASP.NET Web Service如何工作(1)

    ASP.NET Web Service如何工作(1) [日期:2003-06-26] 来源:CSDN  作者:sunnyzhao(翻译) [字体:大 中 小] Summary ASP.NET Web ...

  5. struts2中<s:property>的用法

    1,访问Action值栈中的普通属性: <s:property value="attrName"/> 2,访问Action值栈中的对象属性(要有get set方法):  ...

  6. 07_XPath_01_入门

    [工程截图] [person.xml] <?xml version="1.0" encoding="UTF-8"?> <students> ...

  7. Custom Action : dynamic link library

    工具:VS2010, Installshield 2008 实现功能: 创建一个C++ win32 DLL的工程,MSI 工程需要调用这个DLL,并将Basic MSI工程中的两个参数,传递给DLL, ...

  8. 重构if...else...或者switch程序块 为 中介者(Mediator)模式.的思考

    http://www.cnblogs.com/insus/p/4142264.html 重构if...else...或者switch程序块 为 中介者(Mediator)模式.的思考 首先普世的编程架 ...

  9. 把URL传递参数转变成自定义实体方法

    先定义下要获取的实体: public class InputClass { public long Id { get; set; } public int Status { get; set; } p ...

  10. [C#]判断是否是合法的IP4,IP6地址

    判断一个字符串如果没有端口的话,利用IPAddress.TryParse很好判断,那么有端口怎么判断呢,正则表达式?还是其他方式? 关键代码: /// <summary> /// 判断是否 ...