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

来源:互联网 发布:调节手机光线软件 编辑:程序博客网 时间:2024/06/05 22:42

分析

在java中,可以使用关键字final来修饰类,使其不能够比继承;而C++要实现不被继承的类需要自己实现;

主要思路

为了使类不被继承,只要使子类不能构造父类的部分,此时子类只能构造新定义的成员,但是没法完成父类继承部分的构造;因此我们只需要把父类的构造函数和解析函数都定义为private类型,此时类就不能被继承了

private的构造函数、解析函数无法得到该类的实例,即该类无法生成实例,因为私有成员无法被类对象直接调用,但是可以通过成员函数间接调用。所以我们可以在类的共有成员函数中定义static来创建和释放类的实例

备注:

为什么要定义static类型的成员函数来调用private的构造函数呢
C++primer里面讲过:static成员它不像普通的数据成员,static数据成员独立于该类的任意对象而存在,每个static数据成员是与类关联的对象,并不与该类的对象相关联!
这句话可能比较拗口,其实可以这么理解:每个static数据成员可以看成是类的一个对象,而不与该类定义的对象有任何关系!下面我们就来具体看看类中的static数据成员!
注意在类中不能对static数据成员进行初始化,要初始化的话必须在类外进行定义,有个例外,const int 型的static成员便可以在类定义体内部进行初始化。记住一定只能是const int型的,换成const string ,double都不行的。

#include  <iostream>#include  <string>using namespace std;class Person{private:    string name;    static int age;public:    Person(const string&nm):name(nm)    {}    void Print()    {        cout<<name<<" is "<<age<<endl;    }};int Person::age=20;#include "stdafx.h"#include "static.h"#include <iostream>using namespace std;int _tmain(int argc, _TCHAR* argv[]){        Person person("tom");    person.Print();    cout<<endl;    return 0;}

程序示例:

class FinalClass1{   public:   static FinalClass1* GetInstance()   {    return new FinalClass1;   }   staic void DeleteInstance(FinalClass1* pInstance)   {    delete pInstance;    pInstance=0;   }   private:   FinalClass1();   ~FinalClass1();}

存在问题

现在FinalClass1这个类是不能被继承了,但是通过这种方法得到的实例都在堆上,得需要程序员手动释放;
注:
堆:一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式是类似于链表。可能用到的关键字如下:new、malloc、delete、free等等。需要程序员自己申请,并指明大小。

栈:由编译器(Compiler)自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。 使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。

改进

#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; //栈上对象 }

如果有类想要继承FinalClass类时,无法实现;因为FinalClass类是从类 Base 虚拟继承过来的,在继承类调用FinalClass构造函数时,会直接跳过FinalClass而直接调用 Base 的构造函数,而新的继承类不是 Base 的友元,无法调用 Base 的私用的构造函数。

0 0
原创粉丝点击