笔试题目:定义一个类不能被继承,且只能被实例化3次 .

转载:http://blog.csdn.net/keepingstudying/article/details/8083366

以下解答是本人在百度上搜到的答案,仅供参考:
在C++ 中没有final 这个关键字,要实现这个要求还是需要花费一些精力。
首先想到的是在C++ 中,子类的构造函数会自动调用父类的构造函数。
同样,子类的析构函数也会自动调用父类的析构函数。要想一个类不能被继承,我们只要把它的构造函数和析构函数都定义为私有函数。

class FinalClass1
{
public static int count ;//实例化次数
public :
      static FinalClass1* GetInstance()
      {
        if(count<=0)
                return NULL;
            count--;
            return new FinalClass1;
      }
      static void setCount(int n)
      {
          count  = n;
       }
      static void DeleteInstance( FinalClass1* pInstance)
      {
            delete pInstance;
            pInstance = 0;
      }
 
private :
      FinalClass1() {}
      ~FinalClass1() {}
};

//测试函数
#include<stdio.h>
int FinalClass1::count=0; 
void main()
{
    FinalClass1::setCount(3);
    FinalClass1 *f1 = FinalClass1::GetInstance();
    FinalClass1 *f2 = FinalClass1::GetInstance();
    FinalClass1 *f3 = FinalClass1::GetInstance();
    if (f3==NULL)
    {
        printf("f3 NULL\n");
    }else{
        printf("f3 Not NULL\n");

   }


    FinalClass1 *f4 = FinalClass1::GetInstance();
    if (f4==NULL)
    {
        printf("f4 NULL\n");
    }
    FinalClass1 *f5 = FinalClass1::GetInstance();
    if (f5==NULL)
    {
        printf("f5 NULL\n");
    }
}
另一篇博客的文章:
  
  

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

设计思路:(1)  在Java 中定义了关键字final的类不能被继承。但在C++ 中没有final 这个关键字。(2)  首先想到的是在C++ 中,子类的构造函数会自动调用父类的构造函数。同样,子类的析构函数也会自动调用父类的析       构函数。要想一个类不能被继承,我们只要把它的构造函数和析构函数都定义为私有函数。那么当一个类试图从它那继       承的时候,必然会由于试图调用构造函数、析构函数而导致编译错误。(3)实现代码如下:  (熟悉设计模式的人知道,这也是最简单的设计模式------单例模式的核心代码)class FinalClass {  public :   static FinalClass* GetInstance()   {           return new FinalClass;       }       static void DeleteInstance( FinalClass* pInstance)       {             delete pInstance;          pInstance = 0;     } private :       FinalClass()  {}     ~FinalClass() {}  }这是一个不能继承的类,但是我们只能得到位于堆上的实例,而得不到位于栈上实例。为了这一目的,我们如下做:template<typename  T>class  MakeFinal{       friend   T;    private:                MakeFinal() {}               ~MakeFinal() {}};class  FinalClass: virtual  public  MakeFinal<FinalClass>{public:     FinalClass() {}      ~FinalClass() {}};     注意:MakeFinal<FinalClass>的构造函数和析构函数都是私有的,但由于类FinalClass是它的友元函数,因此在FinalClass中调用MakeFinal<FinalClass>的构造函数和析构函数都不会造成编译错误。但当我们试图从FinalClass继承一个类并创建它的实例时,却编译错误。class   MyTry : public    FinalClass{  public:       MyTry() {}       ~MyTry() {}};由于类FinalClass是从类MakeFinal<FinalClass>虚继承过来的,在调用MyTry 的构造函数的时候,会直接跳过FinalClass而直接调用MakeFinal<FinalClass>的构造函数。非常遗憾的是,MyTry 不是MakeFinal<FinalClass>的友元,因此不能调用其私有的构造函数。

基于上面的分析,试图从FinalClass继承的类,一旦实例化,都会导致编译错误,因此是FinalClass不能被继承。但是我们可以这样来让FinalClass能够被继承:

 #include  <iostream.h> class  Mytry; template <typename T>  class MakeFinal {       friend T;  friend Mytry;//注意这里 private :       MakeFinal() {cout<<"MakeFinal()------------------------------"<<endl;}    ~MakeFinal() {} }; class FinalClass : virtual public MakeFinal<FinalClass> { public :       FinalClass() {cout<<"FinalClass()------------------------------"<<endl;}       ~FinalClass(){} }; class Mytry: public FinalClass { public :       Mytry() {cout<<"Mytry()------------------------------"<<endl;}       ~Mytry() {} };

在其他地方定义     Mytry   A;编译则不会出错

最后,

            相似的,我们也可以用多重继承,同样的思想(屏蔽私有构造函数的方法)来实现,代码如下:

 #include <iostream> using namespace std;

template <typename T> class CFinalClassBase{    friend T;    private:        CFinalClassBase()      {        cout << "I am the CFinalClassBase" << endl;     }        ~CFinalClassBase()     {     } };

class XXX {   public:     XXX()  {      cout << "I am XXX" << endl;  }     ~XXX()  {  } };

class CParent:virtual public CFinalClassBase<CParent>, public XXX {   public:       CParent()      {     }       ~CParent()      {     } }; class CChild: public CParent { };

int main(int argc, char* argv[]) {     CParent a; // 可以构造     //CChild b; //不能构造     return 0; } 这样,我们只要继承自CFinalClassBase(或单继承或多重继承),我们就得到了不能继承的类了。当然,对纯静态成员的类是特例,我们无可奈何!另当别论!



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值