32.不能被继承的类

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

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

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

在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() {}
};

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


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!

return 0;
}

OK。现在看看我们的Finalclass类。

继承于Base,Base为虚基类,因为它是Base的友元,所以,它可以访问基类的私有构造函数,以及析构函数。编译运行时是正确的。也就是说,可以创建堆上的对象,并且可以构建栈上的对象。

可否继承?假如它作为一个基类被一个类继承,在编译时是完全可以通过的。

这一点没有什么疑问,问题就出在运行时:当子类在构造对象时,因为是虚继承,所以子类的构造函数会直接去调用Base类的构造函数,而Base的构造函数是私有的,运行错误error!!!

这就是一个真正不能被继承的类。

时间: 2024-08-25 22:29:22

32.不能被继承的类的相关文章

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

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

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

不能被继承的类

题目:用C++设计一个不能被继承的类. 常规的解法:把构造函数设为私有函数 我们通过定义共有的静态函数来创建和释放类的实例. class SealedClass1 { public: static SealedClass1* GetInstance() {return new SealedClass1();} static void DeleteInstance(SealedClass1* pInstance) {delete pInstance;} private: SealedClass1(

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++)

不能被继承的类(私有构造函数) 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 用C++设计一个不能被继承的类. 可以使用私有构造函数, 并提供静态成员函数, 返回和删除类的实例. 则只能在堆上创建实例, 不能在栈上创建. 代码: /* * main.cpp * * Created on: 2014.7.13 * Author: Spike */ #include <iostream> #include <list> us

编程算法 - 不能被继承的类(模板参数友元) 代码(C++)

不能被继承的类(模板参数友元) 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 用C++设计一个不能被继承的类. 可以使用模板类模板参数友元, 模板类私有构造函数, 类虚继承这个模板类, 如果类被其他类继承时, 则虚继承会直接调用模板类, 无法构造. 代码: /* * main.cpp * * Created on: 2014.7.13 * Author: Spike */ /*eclipse cdt, gcc 4.8.1*/ #inc

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

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

C++ 实现不能被继承的类

方法一: #include <iostream> using namespace std; class A { public: static A* getInstance(); static void deleteInstance(A* pA); private: A() { cout << "construct A\n";} ~A() { cout << "destruct A\n"; } }; A* A::getInstanc