私有继承:
当类的继承方式为私有继承是,基类中的公有成员和保护成员都以私有成员身份出现在派生类中,而基类的私有成员在派生类中不可直接访问。也就是说基类的公有成员和保护成员被继承后作为派生类的私有成员,派生类的其他成员可以直接访问他们,但是在类族外部通过派生类的对象无法直接访问他们。无论是派生类的成员还是通过派生类的对象,都无法直接访问从基类继承的私有成员。
经过私有继承之后,所有基类的成员都成为了派生类的私有成员或不可直接访问的成员,如果进一步派生的话,基类的全部成员就无法在新的派生类中被直接访问。因此,私有继承之后,基类的成员再也无法在以后的派生类中直接发挥作用,实际是相当于中止了基类功能的继续派生,出于这种原因,一般情况下私有继承的使用比较少。
代码说明:
#include<iostream>
#include<cassert>
using namespace std;
class point
{
public:
void initpoint(float x=0,float y=0)
{
this->x=x;
this->y=y;
}
void move(float offx,float offy) {x+=offx;y+=offy;}
float getx() const {return x;}
float gety() const {return y;}
private:
float x,y;
};
class rectangle:private point{
public:
void initrectangle(float x,float y,float w,float h)
{
initpoint(x,y);
this->w=w;
this->h=h;
}
void move(float offx,float offy) {point::move(offx,offy);}
float ggggggetx() const {return getx();}
//float gety() const {return gety();}//错误,同名隐藏使系统默认调用派生类的gety(),所以运行时会出现错误
float gety() const {return point::gety();}//point::是出现了同名隐藏的情况下,想要调用基类的gety() 来保证系统运行不出现错误的解决方案。
//有没有必要加point:: 是看派生类中是否有同名函数
float geth() const {return h;}
float getw() const {return w;}
private:
float w,h;
};
int main()
{
rectangle rect;
rect.initrectangle(2,3,20,10);
rect.move(3,2);
cout<<"the data of rect(x,y,w,h):"<<endl;
//cout<<rect.getx();错误
cout<<rect.ggggggetx()<<","<<rect.gety()<<","<<rect.getw()<<","<<rect.geth()<<endl;
return 0;
}
基类的原有的外部接口被派生类封装和隐蔽起来。当让,派生类新增的成员之间仍让可以自由的互相访问。
在私有继承的情况下,为了保证基类的一部分外部接口特征能有在派生类中也存在,就必须在派生类中重新声明同名的成员。这里在派生类retangle中,重新声明了move,getx,gety等函数,利用派生类对基类成员的访问能力,把基类的原有成员函数的功能照搬过来。这种在派生类中重新声明的成员函数比基类同名成员函数更小的作用域,因此在调用时,根据同名隐藏的原则,自然会使用派生类的函数。