派生类在已有的类(基类)中派生而来的,在原来类的基础上增加了原来的类没有的一些特性。
例如:车->运输车,若把车看成一个类,车是已有的称为父类,运输车被称为子类。车也被成为基类,运输车称为派生类。描述类的层次性的机制是继承,继承的过程称为派生。
说了这么多,派生类存在的意义呢?
派生类使得我们无需修改已有的类,只需在已有类的基础上,增加或者修改少量代码得到新的类,很好的解决了代码重用的问题。
那么派生类的概念就讲到这里吧,接下来我们聊聊基类成员在派生类中的访问属性。
派生类的继承声明方式:
class 派生类名:继承方式 基类名{
...
};
派生类的继承方式有三种:
1、private(私有继承)
2、public(公有继承)
3、protected(保护继承)
因为继承方式的不同,导致派生类继承来的访问属性也有一丢丢差异,那么接下来我就分别来介绍这三种访问方式的一些访问特性。
No1、private(私有派生类)
class A{
private:
int x;
public:
int y;
protected:
int z;
};
class B:private A{
x不可直接访问,因为x是声明的私有成员
y访问属性是私有成员类型
z访问属性是私有成员类型
};
No2、public(公有派生类)
class A{
private:
int x;
public:
int y;
protected:
int z;
};
class B:public A{
x不可直接访问,因为x是声明的私有成员
y访问属性是公有成员类型
z访问属性是保护成员类型
};
No3、protected(保护派生类)
class A{
private:
int x;
public:
int y;
protected:
int z;
};
class B:protected A{
x不可直接访问,因为x是声明的私有成员
y访问属性是保护成员类型
z访问属性是保护成员类型
};
那么根据以上描述的种种,我们可以做一些总结啦!
总结如下:
① 公有派生时,基类中的所有公有成员在派生类中也都是公有成员,基类中的所有保护成员在派生类中仍然是保护成员。
② 保护派生时,基类中的所有公有成员和保护成员在派生类中是保护成员。
③ 私有派生时,基类中的所有公有成员和保护成员在派生类中是私有成员。
**注意!**基类中的私有成员很任性的,它在任何方式的派生类中都不可以直接访问。
派生类做的工作:
首先:
派生类要继承基类的成员,当然不能把基类中所有成员打包接收过来,基类中的构造函数和析构函数不接收哦,除此之外,其他的所有就接收了。
其次:
派生类要对从基类接受的成员进项选择和调整。第一个就是改变基类成员在派生类中的访问属性;第二个就是派生类对基类的成员进行重新定义(派生类的成员会覆盖基类中的同名成员,成员函数呢,则要函数名和参数表和基类一致)。
最后:
在派生类中增加新的成员。增加新成员体现了对基类的功能特性的扩展。
ok,接下来我们看看派生类对基类成员的访问规则:
访问属性有两种:
内部访问(派生类新增成员函数对继承的成员的访问)
对象访问(在派生类外部,派生类的对象对继承的成员访问)
私有继承的访问规则:
声明一个基类A
class A{
public:
void xx(int n){x=n}
void xxx(){cout<<x<<endl;}
private:
int x;
};
声明一个从A派生来的私有派生类B
class B:private A{
public:
void xy(int n,int m){
xx(n);//xx为私有成员函数,派生成员函数可以访问
y=m;
}
void xxy(){
cout<<x;//错误,x是基类的私有成员
cout<<y<<endl;
}
private:
int y;
};
写一个main函数:
int main(){
B b;
b.xx(2);//错,xx是B中的私有成员派生对象不可以访问
b.xxx();//错,xxx是B中的私有成员,派生类对象同样不可以访问
b.xy(2,22);
b.xxy();
return 0;
}
基类中的私有成员不可以被派生类的对象访问,也不可以被成员函数访问。
总结:
私有继承的访问规则是:
对象访问六亲不认,无论是基类中的私有成员,公有成员还是保护成员都不可访问。
内部访问不可访问基类的私有成员,但是可以访问公有成员和保护成员。
公有继承的访问规则:
声明一个类A
class A{
public:
void xx(int m,int n)
{
x=m;
y=n;
}
void xy(){
cout<<"x="<<x<<endl;
cout<<"y="<<y<<endl;
}
private:
int x;
protected:
int y;
};
声明一个派生类B
class B:public A{
public:
void xyz(int m,int n,int i)
{
xx(m,n)//函数xx在B中是public成员,派生成员函数可以访问
z=1;
}
void xxxyz()
{
cout<<"x="<<x<<endl;//错误,x在B中为不可直接访问的成员
cout<<"y="<<y<<endl;//正确,y在B中为保护成员,派生类成员函数可以访问
cout<<"z="<<z<<endl;
private:
int z;
};
写一个main函数
int main(){
B b;
b.xyz(2,22,222);
b.xy();//正确,函数xx在B中为公有成员,派生类对象可以访问它
b.y=2222;//错误,y在B中为保护成员,派生类对象不可以访问它
b.xxxyz();
return 0;
}
总结:
公有继承访问规则:
内部访问:私有成员不可以访问,但是公有成员和保护成员可访问
对象访问:公有成员可访问,但是私有成员和保护成员不可访问。
保护继承的访问规则:
声明一个类A
class A{
public:
int z;
void x(int i)
{x=i;}
int xy()
{return x;}
private:
int x;
protected:
int y;
};
声明一个派生类B
class B:protected A{
public:
int m;
void st(int a,int b,int c,int d,int e,int f);
void sh();
private:
int q;
protected:
int n;
};
void B::st(int a,int b,int c,int d,int e,int f)
{
x=a;//错误,在B中x为不可直接访问成员
y=b;//正确,y为保护成员,派生对象可访问
z=c;//同y
q=d;
n=e;
m=f;
}
void B::sh(){
cout<<"x="<<x<<"\n";//错误,X在类B为不可直接访问成员
cout<<"x="<<xy()<<"\n";//正确,xy在派生类中为保护成员
cout<<"y="<<y<<"\n";//正确
cout<<"z="<<z<<"\n";//正确
cout<<"q="<<q<<"\n";//正确,q为B的私有成员,派生函数可以访问
cout<<"n="<<n<<"\n";//正确,n为B的保护成员,派生类函数可以直接访问
}
写一个main函数
int main(){
B b;
b.st(1,11,111,2,22,222);
b.sh();
cout<<"y="<<b.y<<endl;//错误,y是派生类的保护成员,派生对象不可访问
cott<<"m="<<o.m<<endl;//正确,为派生类B的公有成员,派生对象可以访问
return 0;
}
总结:
保护继承的访问规则:
内部访问:私有成员不可访问,公有成员和保护成员可访问。
对象访问:私有成员和公有成员和保护成员都不可以访问。
派生类访问基类的私有成员:
1:在基类中定义保护成员,将传递给派生类的私有成员定义为保护成员
2:将访问基类私有成员的派生类函数定义友元函数
class A{
friend class C;//声明友元
int x;
protected:
int y;
};
class B:A{//默认为私有类型
public:
int getx(){return x;}//错误,x为私有成员
int gety(){return y;}//正确,y为保护成员
};
class C:A{//默认为私有类型
public:
int getx();
};
int C::getx(){
A c;
return c.x;//正确,友元能访问基类的私有成员
}