1 #include<iostream> 2 using namespace std; 3 class Gradpa 4 { 5 friend class Parent;//声明public或者private都无影响 6 private: 7 Gradpa(){ 8 cout<<"I m Gradpa"<<endl; 9 }; 10 ~Gradpa(){}; 11 12 }; 13 14 class Parent: virtual public Gradpa 15 { 16 public: 17 Parent(){ 18 cout<<"I m Parent"<<endl; 19 }; 20 ~Parent(){}; 21 }; 22 23 class Child:public Parent 24 { 25 public: 26 Child(){ 27 cout<<"I m Child"<<endl; 28 } 29 ~Child(){} 30 }; 31 32 int main() 33 { 34 //Gradpa* gra=new Gradpa; //构造函数声明为private,不能直接访问 35 Parent* par=new Parent; //通过声明一个friend 类,访问private的构造函数 36 Child * chd=new Child; //子类能够继承父类,但是Parent加上virtual 后变成虚继承,Child类就得直接去访问Gradpa,导致出错。保证Parent类不能被继承 37 system("pause"); 38 return 0; 39 40 }
错误 1 error C2248: “Gradpa::Gradpa”: 无法访问 private 成员(在“Gradpa”类中声明) e:\my projects\不能被继承的类.cpp 26
可参考详细转载,转载地址为:http://blog.163.com/xiangzaihui@126/blog/static/166955749201182295845689/
在C++中,子类的构造函数会自动调用父类的构造函数子类的析构函数也会自动调用父类的析构函数。
要想一个类不能被继承,我们只要把它的构造函数和析构函数都定义为私有函数。
那么当一个类试图从它那继承的时候,必然会由于试图调用构造函数、析构函数而导致编译错误。
可是这个类的构造函数和析构函数都是私有函数了,我们怎样才能得到该类的实例呢?这难不倒我们,我
们可以通过定义静态来创建和释放类的实例。基于这个思路,我们可以写出如下的代码:
class FinalClass1
{
public
:
static FinalClass1*
GetInstance()
{
return
new FinalClass1;
}
static void DeleteInstance(
FinalClass1* pInstance)
{
delete
pInstance;
pInstance = 0;
}
private
:
FinalClass1()
{}
~FinalClass1()
{}
};
这个类在基本上就能实现不能继承的功能。但是每次如果你都用这样一个类的话,估计你到最后不是你的程序崩溃了,而是你自己崩溃的更早。
因此,我们这样设计。
class CFinalClassMixin
{
friend class
CParent;
private:
CFinalClassMixin(){}
~CFinalClassMixin(){}
};
class
CParent: public
CFinalClassMixin
{
public:
CParent(){}
~CParent(){}
};
class
CChild : public
CParent
{
};
但是发现没有用,想一想也是,CChild构造函数调用CParent的构造函数,而CParent的构造函数再调用CFinalClassMixin的构造函数,很显然是合法的。
我估计你也想骂了,唧唧歪歪讲了这么就还是不行。
但是请你想想,如果我是在CChild的构造函数直接调用CFinalClassMixin的构造函数,而CFinalClassMixin的构造函数是private,不能被调用,那我们岂不是达到了目的,但是我们如何才能在CChild中直接调用CFinalClassMixin的构造函数而不是通过CParent去调用了。
给你一分钟去想想。。。。。。。。。。。。。。
哈哈虚继承,虚继承刚好可以实现上述目的。
因此:
class CFinalClassMixin
{
friend
class
CParent;
private:
CFinalClassMixin(){}
~CFinalClassMixin(){}
};
class
CParent: virtual public
CFinalClassMixin
{
public:
CParent(){}
~CParent(){}
};
哈哈发现CParent不再可以被继承了。
如果你不懂虚继承是个神马东东的话,你可以参考我的另外一篇文章:
虚继承
如果你看懂了,我相信你就懂了上述的方法了。