设计一个不能被继承的类:要求是该类可以像普通类一样正常使用,但是不能被继承
先看一下第一个代码:
class Base
{
private:
Base(int val=0):_val(val){}
private:
int _val;
};
class Dreive:public Base
{
public:
void print()
{
cout<<"Derive::"<<endl;
}
};
int main()
{
Dreive A;
A.print();
return 0;
}
实现是将构造函数放在私有下面。虽然不能被继承,但同时自己也无法在类外调用构造函数构造出一个对象出来。
/////////////////////////////////////////////////
再来看看第二个代码:
class Base
{
private:
Base(int val=0):_val(val){}
private:
int _val;
friend class B;
};
class B:virtual public Base
{
public:
void print()
{
cout<<"B"<<endl;
}
};
class c:public B
{
public:
void print()
{
cout<<"C"<<endl;
}
};
int main()
{
B b;
b.print();
c c;
c.print();
return 0;
}
不可继承的类,不是说不能继承他,而是说他的派生类无法构成对象,而自己的类可以正常使用。先写一个基类A,构造函数放在私有下面,并定义友元类B,再写一个虚继承的派生类B,因为B是A的友元,所以B可以调用A中私有的构造函数,而且B的构造函数就在共有下,所以类外可以调用B的构造函数创建对象。现在类B就是一个不可被继承的类,因为如果再写一个类C继承B,类C在构造基类部分时需要调用A的构造函数,但是类C和类A没有友元关系,所以导致构造失败。为什么又变成类C调用A的构造函数了呢?这就是虚继承的原因了,这也是构造一个不可被继承的类的关键。
为什么要用虚继承呢???
当继承是虚继承时,会产生一个虚表指针(vbptr)指向一个虚继承表(vbtable),而基类的私有部分也会被移到当前作用域的最下面,所以当类C继承B之后,也会将A部分的构造函数移到自己当前作用域的最下面,故构造的时候不能成功构造。