设计一个类不能被继承
在C++继承中,子类的构造函数会自动调用父类的构造,子类的析构会自动调用父类的析构。
一个简单的例子:
class AA
{
public:
AA()
{
cout << "AA()" << endl;
}
~AA()
{
cout << "~AA()" << endl;
}
};
class BB:public AA
{
public:
BB()
{
cout << "BB()" << endl;
}
~BB()
{
cout << "~BB()" << endl;
}
};
int main()
{
BB tty;
return 0;
}
由上述可见,那是不是将父类的构造,析构都定义为私有就可以了呢?
解一:将父类的构造,析构都定义为私有,要求:父类单独作为一个类,必须可以正常使用
很明显,一个类的构造,析构均为私有,在类外是无法生成对象的,所以需要使用静态成员函数
class AA
{
public:
static AA* Typ()
{
AA* p = new AA; //创建对象
cout << "static AA* Typ" << endl;
return p;
}
static void Delete(AA* qqw)
{
cout << "static void Delete" << endl;
delete qqw; //清理空间
qqw = NULL;
}
private:
AA()
{
cout << "AA()" << endl;
}
~AA()
{
cout << "~AA()" << endl;
}
};
int main()
{
AA *tty = AA::Typ(); //在堆上创建对象
//BB qp;
return 0;
}
PS:
此时构建的AA类是符合条件的,可以单独编译,可以正常使用。
此时的类不能被继承,因为其构造,析构是私有的。
缺陷:
1.使用不方便,静态成员函数需要使用类型::作用域访问符直接调用静态成员函数
2.由静态成员函数创建的对象只能得到在堆上的实例,无法得到在栈上的实例。
3.静态成员函数不能被继承
优化:解2:利用虚继承(利用的是友元的特性,使得BB可以访问AA 的私有成员)
template<class T>
class AA
{
public:
friend T;
private:
AA()
{
cout << "AA()" << endl;
}
~AA()
{
cout << "~AA()" << endl;
}
};
class BB:virtual public AA<BB> //此时BB是AA的友元,可以访问AA中的任何成员
{
public:
BB()
{
cout << "BB()" << endl;
}
~BB()
{
cout << "~BB()" << endl;
}
};
int main()
{
BB* p = new BB; //在堆上创建对象
BB tty; //在栈上创建对象
return 0;
}
因为BB是AA的友元,所以,它可以访问父类的私有成员,构造,析构,所以可以创建对象,编译正确。
可以在堆上创建对象,也可以在栈上创建对象。
那能否继承呢?当在写一个类去继承BB 时,无法编译
子类在构造对象时,因为是虚继承,所以子类的构造函数会直接去调用父类的构造函数,而AA的构造函数是私有的。运行错误error!!!
这就是一个真正不能被继承的类。
友元的特性:
1.友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
2.友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明
3.友元关系不能继承,基类的友元对派生类的成员没有特殊的访问权限。如果基类被授予友元关系,则只有基类具有特殊的访问权限。该基类的派生类不能访问授予友元关系的类。