分析
在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 的私用的构造函数。