继承与派生二.docx
《继承与派生二.docx》由会员分享,可在线阅读,更多相关《继承与派生二.docx(11页珍藏版)》请在冰点文库上搜索。
![继承与派生二.docx](https://file1.bingdoc.com/fileroot1/2023-5/24/b859d4f1-3307-48bf-8135-3b7cf58e15ce/b859d4f1-3307-48bf-8135-3b7cf58e15ce1.gif)
继承与派生二
//类型兼容规则举例。
本例演示子类对象(指针)可赋给父类对象(指针),
//但:
通过基类的对象名、指针只能使用从基类继承的成员
#include
usingnamespacestd;
classB0//基类B0声明
{public:
voiddisplay(){cout<<"这是基类B0的display()"<};
classB1:
publicB0
{
public:
voiddisplay(){cout<<"这是一级子类B1的display()"<};
classD1:
publicB1
{
public:
voiddisplay(){cout<<"这是二级子类D1的display()"<};
voidfun(B0*ptr)
{ptr->display();}//"对象指针->成员名"
voidmain(void)
{
B0b0;//声明B0类对象
B1b1;//声明B1类对象
D1d1;//声明D1类对象
B0*p;//声明B0类指针
p=&b0;//B0类指针指向B0类对象
fun(p);
p=&b1;//B0类指针指向B1类对象
fun(p);
p=&d1;//B0类指针指向D1类对象
fun(p);
}
//多继承示例,本例中类C从类A和类B继承
#include
usingnamespacestd;
classA{
public:
voidsetA(int);
voidshowA();
private:
inta;
};
classB{
public:
voidsetB(int);
voidshowB();
private:
intb;
};
classC:
publicA,privateB{
public:
voidsetC(int,int,int);
voidshowC();
private:
intc;
};
voidA:
:
setA(intx)
{a=x;}
voidB:
:
setB(intx)
{b=x;}
voidC:
:
setC(intx,inty,intz)
{//派生类成员直接访问基类的公有成员
setA(x);//基类A的公有成员
setB(y);//基类B的公有成员
c=z;
}
//其它函数实现略
voidmain(void)
{
Cobj;
obj.setA(5);
obj.showA();
obj.setC(6,7,9);
obj.showC();
//obj.setB(6);错误,原因:
C是通过私有方式继承B,B中的公有成员相当
//于C的私有成员,不能通过对象访问(对象指针也不可以)
//obj.showB();错误,原因同上
}
//单一继承时的构造函数举例。
本例演示了子类构造函数如何向基类构造函数传//递参数,同时需注意子类C中的Print函数式如何复用基类功能的
#include
usingnamespacestd;
//------------------------------------------------------------------------
//类B的定义
//------------------------------------------------------------------------
classB
{
public:
B();
B(inti);
~B();
voidPrint()const;
private:
intb;
};
//------------------------------------------------------------------------
B:
:
B()
{
b=0;
cout<<"B的默认构造函数被调用."<}
//------------------------------------------------------------------------
B:
:
B(inti)
{
b=i;
cout<<"B的带参构造函数被调用."<}
//------------------------------------------------------------------------
B:
:
~B()
{cout<<"B的析构函数被调用."<//------------------------------------------------------------------------
voidB:
:
Print()const
{cout<<"B:
:
Print()被调用b="<
//------------------------------------------------------------------------
//类C的定义
//------------------------------------------------------------------------
classC:
publicB
{
public:
C();
C(inti,intj);
~C();
voidPrint()const;
private:
intc;
};
//------------------------------------------------------------------------
C:
:
C()
{
c=0;
cout<<"C的默认构造函数被调用."<}
//------------------------------------------------------------------------
C:
:
C(inti,intj):
B(i)//重点:
子类C的构造函数给基类构造函数传递参数i
{c=j;
cout<<"C的带参构造函数被调用.."<}
//------------------------------------------------------------------------
C:
:
~C()
{cout<<"C的析构函数被调用."<//------------------------------------------------------------------------
//注意:
这是面向对象常用的招数:
需要增加子类新的功能,但又需要用到基类的相关
//功能,则覆盖基类函数,方法是:
1、先完整的引用基类函数;2、添加新功能
//这就实现了代码复用
voidC:
:
Print()const
{B:
:
Print();cout<//------------------------------------------------------------------------
voidmain()
{
CobjC(5,6);//思考此处定义C的对象objC时,将发生什么?
objC.Print();
}
//多继承且有内嵌对象时的构造函数
#include
usingnamespacestd;
//------------------------------------------------------------------------
//类B1的定义
//------------------------------------------------------------------------
classB1//基类B1,构造函数有参数
{public:
B1(inti){cout<<"B1构造函数"<
};
//------------------------------------------------------------------------
//类B2的定义
//------------------------------------------------------------------------
classB2//基类B2,构造函数有参数
{public:
B2(intj){cout<<"B2构造函数"<};
//------------------------------------------------------------------------
//类B3的定义
//------------------------------------------------------------------------
classB3//基类B3,构造函数无参数
{public:
B3(){cout<<"B3构造函数"<};
//------------------------------------------------------------------------
//类C的定义,注意其特殊性,一是从三个基类继承,二是有三个内嵌对象
//定义C的构造函数时,必须对不存在无参构造函数的基类构造函数传递参数,
//同时对不存在无参构造函数的对象成员传递参数
//思考1、C的构造函数似乎没对memberB3初始化?
//思考2、C的构造函数若定义成如下方式,有何问题?
//C(inta,intb,intc,intd):
B1(a),memberB1(c),B2(b){}
//观察:
程序运行后基类构造函数调用次序(包括成员对象初始化对构造函数的调用)
//------------------------------------------------------------------------
classC:
publicB2,publicB1,publicB3
{
public:
//派生类的公有成员
C(inta,intb,intc,intd):
B1(a),memberB2(d),memberB1(c),B2(b)
{
}
private:
//派生类的私有对象成员
B1memberB1;
B2memberB2;
B3memberB3;
};
voidmain()
{Cobj(1,2,3,4);}
//派生类析构函数举例
#include
usingnamespacestd;
//----------------------------------------------------------------
classB1//基类B1声明
{public:
B1(inti){cout<<"B1构造"<
~B1(){cout<<"B1析构"<};
//----------------------------------------------------------------
classB2//基类B2声明
{public:
B2(intj){cout<<"B2构造"<~B2(){cout<<"B2析构"<};
//----------------------------------------------------------------
classB3//基类B3声明
{public:
B3(){cout<<"B3构造"<~B3(){cout<<"B3析构"<};
//----------------------------------------------------------------
classC:
publicB2,publicB1,publicB3
{public:
C(inta,intb,intc,intd):
B1(a),memberB2(d),memberB1(c),B2(b){}
private:
B1memberB1;
B2memberB2;
B3memberB3;
};
//----------------------------------------------------------------
voidmain()
{Cobj(1,2,3,4);}
//----------------------------------------------------------------
//同名隐藏示例,注意子类D1在同名覆盖情况下是如何访问基类成员的
#include
usingnamespacestd;
//----------------------------------------------------------------
classB1//声明基类B1
{public:
//外部接口
intnV;
voidfun(){cout<<"B1的成员函数fun"<};
//----------------------------------------------------------------
classB2//声明基类B2
{public:
//外部接口
intnV;
voidfun(){cout<<"B2的成员函数fun"<};
//----------------------------------------------------------------
classD1:
publicB1,publicB2
{public:
intnV;//同名数据成员
voidfun(){cout<<"D1的成员函数fun"<};
//----------------------------------------------------------------
voidmain()
{D1d1;
d1.nV=1;//对象名.成员名标识,访问D1类成员
d1.fun();
d1.B1:
:
nV=2;//作用域分辨符标识,访问基类B1成员
d1.B1:
:
fun();
d1.B2:
:
nV=3;//作用域分辨符标识,访问基类B2成员
d1.B2:
:
fun();
}