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

一道笔试题的思考:

记得,找工作时,遇到了这样的一道笔试题。记不清是那个公司的笔试题,反正觉得自己当时还真费了一点功夫的,但是也就搞定了一部分,结果还是被另一部分给鄙视啦!

现在静下来分析实现如下:

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

不能被继承?不能被继承?不能被继承?按照继承的理论知识分析,我们只要把类的构造函数设置为私有的,即可解决问题。

因为那样的话,子类就没有办法访问基类的构造函数,从而就阻止了进行子类构造对象的任务实现,也就达到了不可继承的目的。

但是,假设那样,这个类我们在其它地方怎么使用呢?那这样子给我们的利用也造成了一定的障碍。

好了。你是不是也想到了,定义静态方法,在方法内部实现一个对象,然后返回它的指针。

Ok?那怎么释放掉呢?再照样设计一个释放内存函数,问题就会迎刃而解。

OK。按照这个逻辑分析。示例代码如下:

#include<iostream>
using  namespace std;
class  A
{
public:
    static  A * Construct(int  n)
    {
        A *pa = new A;
        pa->num = n;
        cout<<"num  is:"<<pa->num<<endl;
        return pa;
    }
    static  void Destruct(A * pIntance)
    {
        delete  pIntance;
        pIntance = NULL;
    }
private:
    A(){}
    ~A(){}
public:
    int num;
};
void  main()
{
    A *f = A::Construct(9);
    cout<<f->num<<endl;
    A::Destruct(f);
}
好了,这个类就这样子。按照我们的理论分析,我们的实践结果是完全成立的。

但是,这个题,它比较有挑战性,什么意思呢?难道你没有发现,咱们这水平也就仅仅有面试资格,还不可以破格录用的。

怎么啦?你可能会反问我。难道你真的没有看明白?确定没有看明白?如果是真的话,那我就告诉你吧!

咱们的类不可以实现在栈上创建对象。也就是说,仅仅只可以在堆上构建任何的一个对象,而在栈上就无能为力了。

私有的构造函数极大的局限性就这样一览无余了。

好吧!我们修改它,也就是所谓的为它打“补丁吧”,请看示例代码:

#include<iostream>
using namespace std;
template <typename T>
class Base
{
    friend T;
private:
    Base() {}
    ~Base() {}
};

class Finalclass : virtual public Base<Finalclass>
{
public:
    Finalclass() {}
    ~Finalclass() {}
};
void  main()
{
    Finalclass  *p = new Finalclass;  //堆上对象
    Finalclass  fs;                 //栈上对象
}
OK。现在看看我们的Finalclass类。

继承于Base,Base为虚基类,因为它是Base的友元,所以,它可以访问基类的私有构造函数,以及析构函数。编译运行时是正确的。

也就是说,可以创建堆上的对象,并且可以构建栈上的对象。

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

这一点没有什么疑问,问题就出在运行时:

当子类在构造对象时,因为是虚继承,所以子类的构造函数会直接去调用Base类的构造函数,而Base的构造函数是私有的。运行错误error!!!

这就是一个真正不能被继承的类。转载自:http://www.cnblogs.com/Braveliu/archive/2013/01/03/2842739.html
时间: 2024-10-13 20:08:36

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

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

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

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

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

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

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

在Java 中定义了关键字final,被final修饰的类不能被继承. 首先想到的是在C++中,子类的构造函数会自动调用父类的构造函数.同样,子类的析构函数也会自动调用父类的析构函数.要想一个类不能被继承,只要把它的构造函数和析构函数都定义为私有函数.那么当一个类试图从它那继承的时候,必然会由于试图调用构造函数.析构函数而导致编译错误. 可是这个类的构造函数和析构函数都是私有函数了,怎样才能得到该类的实例呢?可以通过定义静态来创建和释放类的实例.基于这个思路,可以写出如下的代码: 1 /////

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

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

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

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