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

在Java 中定义了关键字final,被final修饰的类不能被继承。

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

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

 1 ///////////////////////////////////////////////////////////////////////
 2 // Define a class which can‘t be derived from
 3 ///////////////////////////////////////////////////////////////////////
 4 class FinalClass1
 5 {
 6 public :
 7       static FinalClass1* GetInstance()
 8       {
 9             return new FinalClass1;
10       }
11
12       static void DeleteInstance( FinalClass1* pInstance)
13       {
14             delete pInstance;
15             pInstance = 0;
16       }
17
18 private :
19       FinalClass1() {}
20       ~FinalClass1() {}
21 };

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

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

 1 ///////////////////////////////////////////////////////////////////////
 2 // Define a class which can‘t be derived from
 3 ///////////////////////////////////////////////////////////////////////
 4 template <typename T>
 5 class MakeFinal
 6 {
 7       friend T;
 8
 9 private :
10       MakeFinal() {}
11       ~MakeFinal() {}
12 };
13
14 class FinalClass2 : virtual public MakeFinal<FinalClass2>
15 {
16 public :
17       FinalClass2() {}
18       ~FinalClass2() {}
19 };

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

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

1 class Try : public FinalClass2
2 {
3 public :
4       Try() {}
5       ~Try() {}
6 };
7
8 Try temp; 

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

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

C++11中已经有了final关键字:它的作用是指定类的虚函数不能被该类的继承类重写(override),或者是指定一个类成为一个不能被继承的类(final class)。

 1 struct A
 2 {
 3     virtual void foo() final;
 4 };
 5
 6 struct B final : A
 7 {
 8     void foo(); // Error: foo cannot be overridden as it‘s final in A
 9 };
10
11 struct C : B // Error: B is final
12 {
13 };
时间: 2024-10-30 00:18:58

用C++设计一个不能被继承的类(转)的相关文章

c++设计一个不能被继承的类,原因分析

用C++实现一个不能被继承的类(例1) #include <iostream> using namespace std; template <typename T> class Base{     friend T; private:     Base(){         cout << "base" << endl;     }     ~Base(){} }; class B:virtual public Base<B>

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

摘要:使用友元.私有构造函数.虚继承等方式可以使一个类不能被继承,可是为什么必须是虚继承?背后的原理又是什么? 用C++实现一个不能被继承的类(例1) 1 #include <iostream> 2 using namespace std; 3 4 template <typename T> 5 class Base{ 6 friend T; 7 private: 8 Base(){ 9 cout << "base" << endl; 1

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

http://blog.sina.com.cn/s/blog_69d9bff30100odlz.html 在Java 中定义了关键字final ,被final 修饰的类不能被继承.但在C++ 中没有final 这个关键字,要实现这个要求还是需要花费一些精力. 首先想到的是在C++ 中,子类的构造函数会自动调用父类的构造函数.同样,子类的析构函数也会自动调用父类的析构函数.要想一个类不能被继承,我们只要把它的构造函数和析构函 数都定义为私有函数.那么当一个类试图从它那继承的时候,必然会由于试图调用

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

一道笔试题的思考: 记得,找工作时,遇到了这样的一道笔试题.记不清是那个公司的笔试题,反正觉得自己当时还真费了一点功夫的,但是也就搞定了一部分,结果还是被另一部分给鄙视啦! 现在静下来分析实现如下: 题目:用C++设计一个不能被继承的类 不能被继承?不能被继承?不能被继承?按照继承的理论知识分析,我们只要把类的构造函数设置为私有的,即可解决问题. 因为那样的话,子类就没有办法访问基类的构造函数,从而就阻止了进行子类构造对象的任务实现,也就达到了不可继承的目的. 但是,假设那样,这个类我们在其它地

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

C++不同于Java,Java中被final关键字修饰的类不能被继承,C++能实现不被继承的类,但是需要自己实现. 为了使类不被继承,最好的办法是使子类不能构造父类的部分,此时子类就无法实例化整个子类.在C++中,子类的构造函数会自动调用父类的构造函数,子类的析构函数也会自动的调用父类的析构函数,所以只要把类的构造函数和析构函数都定义为private()函数,那么当一个类试图从他那儿继承时,必然会由于试图调用构造函数.析构函数而导致编译错误.此时该类即不能被继承. 但由此会造成一个问题,priv

C++之如何实现一个不能被继承的类

C++中如何实现一个不能被继承的类? 在C#中可以使用sealed,Java中可以使用final来表示一个类不能被继承,而在c++中并没有这个,那我们怎么在c++中实现一个不能被继承的类呢? 1.把构造函数设为私有 这是最简单的一种办法了,那就是把构造函数设为私有,因为我们都知道当一个类试图从它那里继承的时候,必定会因为调用基类的构造函数,而基类的构造函数是私有的,这样会导致编译错误: 可是这样我们又怎么获得这个类的实例呢?我们可以定义公有的静态函数来获取和释放,有点类似单例模式~ class

剑指offer (48) c++实现一个不能被继承的类

题目:用c++实现一个不能被继承的类 题解分析: 常规解法: 首先想到的是在C++ 中,子类的构造函数会自动调用父类的构造函数.同样,子类的析构函数也会自动调用父类的析构函数. 要想一个类不能被继承,我们只要把它的构造函数和析构函数都定义为私有函数. 那么当一个类试图从它那继承的时候,必然会由于试图调用构造函数.析构函数而导致编译错误. 可是这个类的构造函数和析构函数都是私有函数了,我们怎样才能得到该类的实例呢? 这难不倒我们,我们可以通过定义静态函数来创建和释放类的实例.基于这个思路,我们可以

如何产生一个不能被继承的类

对于这个问题,我首先想到的是将“父类”的构造函数声明为私有的,这样的话,子类就不能在自己的构造函数中调用父类的构造函数(就算没有显示调用父类的构造函数,编译器也会自动在子类的构造函数中插入调用父类构造函数的代码),于是就实现了不能被继承的类.同时,我们还是要能够产生这个类的对象,所有要公开一个方法,在该方法中调用私有构造函数.这种解法有点像Singleton. class CNoChildren{ public: CNoChildren* createCNoChildren(){ CNoChil

C++中定义一个不能被继承的类

1.一种错误的解法 最开始是从构造函数开始着手(先声明这种方法不能定义一个不能被继承的类,这是一种错误的方法,但是很容易往这方面想),假设存在下面的继承体系: 现在假设B是一个不能被继承的类,那么如果存在B的子类C,那么C的构造过程应该会报错,那么如何能够让B能正常构造而C不能正常构造呢?首先A,B,C的构造函数和析构函数都假设是public的,最开始想的是让B私有继承自A,根据private继承的特性,父类中public和protected的成员在子类中都会变成private的,那么A的构造函