C++ 创建一个不能被继承的类

本文探讨了在C++中如何创建一个不能被继承的类,通过将构造函数和析构函数设为私有,然后通过静态方法获取类的唯一实例。通过单例模式实现了一个不能被继承的类,并讨论了如何使用友元类来实现既能防止继承又能在栈上或堆上创建对象的类。
摘要由CSDN通过智能技术生成
一、分析

在Java中定义了关键字final,被final修饰的类不能被继承。但在C++中没有final这个关键字。

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

可是这个类的构造函数和析构函数都是私有函数了,我们怎样才能得到该类的实例呢?

通过定义静态来创建和释放类的实例。

二、实现

下面是一个单例模式的实现

#include <iostream>
using namespace std;

class Singleton
{
private:
   Singleton() {};
   ~Singleton() {};
   static Singleton *instance;
public:
   static Singleton* GetInstance()
   {
      if (instance == NULL)
      {
         instance = new Singleton();
      }
      return instance;
   }

   static void DeleteInstance()
   {
      if (instance != NULL)
      {
         delete instance;
         instance = NULL;
      }
   }
};

Singleton* Singleton::instance=NULL;//一定要初始化(由于不能在方法体内部初始化,所以就放到外部)

int main()
{
   Singleton *f = Singleton::GetInstance();//不能使用Singleton *f = new Singleton;创建对象
   cout<<f<<endl;//而且是在堆上创建的对象,在函数GetInstance()使用new运算符,new在堆上分配内存

   Singleton::DeleteInstance();

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

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


#include <iostream>
using namespace std;

class MakeFinal
{
   friend class FinalClass2;
private:
   MakeFinal() {}
   ~MakeFinal() {}
};

class FinalClass2 : virtual public MakeFinal
{
public:
   FinalClass2() {}
   ~FinalClass2() {}
};

int main()
{
   FinalClass2 *pFinalClass2 = new FinalClass2;//在堆上创建对象
   FinalClass2 stack_object;//在栈上创建对象

   cout<<pFinalClass2<<" "<<&stack_object<<endl;

   return 0;
}
结果输出为:
实现一个无法被继承的C++类
很明显这两个对象是在不同的内存区域创建的。
这个类使用起来和一般的类没有区别,可以在栈上、也可以在堆上创建实例。尽管类MakeFinal的构造函数和析构函数都是私有的,但由于类FinalClass2是它的友元函数,因此在FinalClass2中调用MakeFinal的构造函数和析构函数都不会造成编译错误。

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

class Try : public FinalClass2

{

public:

Try() {}

~Try() {}

};

Try temp;

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

基于上面的分析,试图从FinalClass2继承的类,一旦实例化,都会导致编译错误,因此是FinalClass2不能被继承。这就满足了我们设计要求。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值