设计一个不能被继承的类

设计一个不能被继承的类:要求是该类可以像普通类一样正常使用,但是不能被继承

先看一下第一个代码:

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部分的构造函数移到自己当前作用域的最下面,故构造的时候不能成功构造。

猜你喜欢

转载自blog.csdn.net/ShWe_yayaya/article/details/81916383