C++实现不能被继承的类的两种方法:
基本的思想就是将构造函数和析构函数都声明为私有成员。但是仅仅这样做是不够的,因为声明为私有成员之后,不仅不能被继承,就连实例化自身的对象也不行了。
这里就有两种方法实现真正的不可被继承的类:
1. 使用static
关键字:
#include<iostream>
using namespace std;
class Base
{
public:
static Base * Construct()
{
Base *p = new Base;
return p;
}
static void Destruct(Base * p)
{
delete p;
p = NULL;
}
private:
Base()
{
cout << "构造函数" << endl;
}
~Base()
{
cout << "析构函数" << endl;
}
};
int main()
{
Base *p = Base::Construct();
Base::Destruct(p);
return 0;
}
运行的结果是:
构造函数
析构函数
使用static关键字可以让我们不用实例化对象即可调用。这样达到的效果就是,构造函数和析构函数是在类中执行的。但是这个方法有一个缺陷就是只能在堆空间上分配,不能在栈空间上实例化对象。
使用虚继承:
#include <iostream> using namespace std; template <typename T> class Base { friend T;//关键之处 private: Base() {} ~Base() {} }; class Derived : virtual public Base<Derived>//关键之处 { public: Derived() {} ~Derived() {} }; class Test : public Derived { }; int main() { Derived* p = new Derived; // 堆上分配 Derived fs; // 栈上分配 //Test temp; // 基类构造函数私有,不能被继承 return 0; }
这种方法应该算是比较好的方法了,因为即可以在堆空间中分配也可以在栈空间中使用。
这是利用了在虚继承中,虚基类是由最终的派生类初始化的,也就是说,最终派生类的构造函数调用了虚基类的构造函数。这点与普通继承不同,在普通继承中,派生类的构造函数只能调用直接基类的构造函数,而不能调用间接基类的。
当本代码中,当我们把虚继承改成普通继承的话,会发现Derived
类是可以被Test
类继承的,原因就是这个。