复习Word文档格式.docx
- 文档编号:22191974
- 上传时间:2023-02-03
- 格式:DOCX
- 页数:29
- 大小:28.66KB
复习Word文档格式.docx
《复习Word文档格式.docx》由会员分享,可在线阅读,更多相关《复习Word文档格式.docx(29页珍藏版)》请在冰豆网上搜索。
●提高系统的可维护性。
●是实现多态性的基础。
派生类的声明
class派生类名:
继承方式基类名
成员声明;
派生类生成过程
●吸收基类成员
派生类接受了基类中除构造函数和析构
函数外的所有成员。
●改造基类成员
–改变基类成员的访问属性
–对基类数据或函数成员的覆盖
●添加新成员
–给派生类增加适当的数据和函数成员以实现新的功能。
●classStudent:
publicPerson//派生类Student
●{
●public:
●//外部接口,调用基类构造函数初始化基类的数据成员
●Student(char*pName,intAge,charSex,char*IdNo,char*Department,floatScore)
●char*GetDepartment(char*Department)//派生类新成员
●private:
●chardepartment[30];
●floatscore;
●};
派生类对象的构成
继承方式
●不同继承方式的影响主要体现在:
1、派生类成员对基类成员的访问控制。
2、派生类对象对基类成员的访问控制。
●三种继承方式
–公有继承
–私有继承
–保护继承
公有继承(public)
●基类的public和protected成员的访问属性在派生类中保持不变,但基类的private成员不可访问。
(1)派生类中的成员函数可以直接访问基类中的public和protected成员,但不能访问基类的private成员。
(2)通过派生类的对象只能访问基类的public成员。
定义3个类:
(1)点类;
(2)圆类;
(3)矩形类
例3-2公有继承举例
classPoint//基类Point类的声明
{public:
//公有函数成员
voidInitP(floatxx=0,floatyy=0)
{X=xx;
Y=yy;
voidMove(floatxOff,floatyOff)
{X+=xOff;
Y+=yOff;
floatGetX(){returnX;
floatGetY(){returnY;
private:
//私有数据成员
floatX,Y;
私有继承(private)
例3-3私有继承举例
保护继承(protected)
●基类的public和protected成员都以protected身份出现在派生类中,但基类的private成员不可访问。
(2)通过派生类的对象不能访问基类中的任何成员
例3-4protected成员举例
classA
{protected:
intx;
}
Voidmain()
{Aa;
a.X=5;
//错误
回答下列问题,并说明原因。
1、派生类B中成员函数f2()能否访问基类A中的成员:
f1()、j1和i1?
2、派生类B的对象b1能否访问基类A中的成员:
3、派生类C中的成员函数f3()能否访问直接基类B中的成员:
f2()、j2和i2?
能否访问间接基类A中的成员:
f1()、j1和i1?
4、派生类C的对象c1能否访问直接基类B中的成员:
f2()、j2和i2?
f1()、j1和i1?
基类与派生类的对应关系
●单继承
–派生类只从一个基类派生。
●多继承
–派生类从多个基类派生。
●多重派生
–由一个基类派生出多个不同的派生类。
●多层派生
–派生类又作为基类,继续派生新的类。
多继承时派生类的声明
继承方式1基类名1,
继承方式2基类名2,...
注意:
每一个“继承方式”,只用于限制对紧随其后之基类的继承。
多继承举例
{public:
voidsetA(int);
voidshowA();
private:
inta;
classB
voidsetB(int);
voidshowB();
intb;
voidA:
:
setA(intx)
{a=x;
voidB:
setB(intx)
{b=x;
voidC:
setC(intx,inty,intz)
{//派生类成员直接访问基类的
//公有成员
SetA(x);
SetB(y);
c=z;
//其它函数实现略
继承时的构造函数
●基类的构造函数不被继承,需要在派生类中自行声明。
●声明构造函数时,只需要对本类中新增成员进行初始化,对继承来的基类成员的初始化由基类完成。
单一继承时的构造函数
派生类名:
派生类名(基类所需的形参,本类成员所需的形参):
基类名(参数)
本类成员初始化赋值语句;
};
单一继承时的构造函数举例
#include<
iostream.h>
classB{
public:
B();
B(inti);
~B();
voidPrint()const;
B:
B()
b=0;
cout<
<
"
B'
sdefaultconstructorcalled."
endl;
B(inti)
b=i;
sconstructorcalled."
<
~B()
sdestructorcalled."
Print()const
b<
classC:
publicB
C();
C(inti,intj);
~C();
voidPrint()const;
intc;
C:
C()
c=0;
C'
C(inti,intj):
B(i)
c=j;
~C()
B:
Print();
c<
intmain()
Cobj(5,6);
obj.Print();
return0;
输出结果:
sconstructorcalled.
5
6
end
作业与上机实习题目
(1)教材:
216页
11、12
(2)上机实验题目:
补充习题(在公共邮箱)
1.分析教材:
例题6-1,
6-2
6-3
6-4
6-5
6-6
2.教材214页:
完成1,2,3,4,理解有关的概念和用途
多继承时的构造函数
派生类名(基类1形参,基类2形参,...基类n形参,本类形参):
基类名1(参数),基类名2(参数),...基类名n(参数)
派生类与基类的构造函数
●当基类中声明有缺省形式的构造函数或未声明构造函数时,派生类构造函数的声明中可以省略对基类构造函数的调用。
●若基类中未声明构造函数,派生类中也可以不声明,全采用缺省形式构造函数。
●当基类声明有带形参的构造函数时,派生类也应声明带形参的构造函数,提供将参数传递给基类构造函数的途径。
多继承且有内嵌对象时
的构造函数
派生类名:
派生类名(基类1形参,基类2形参,...基类n形参,本类形参):
基类名1(参数),基类名2(参数),...基类名n(参数),对象数据成员的初始化
本类成员初始化赋值语句;
};
构造函数的调用次序
1.调用基类构造函数,调用顺序按照它们被继承时声明的顺序(从左向右)。
2.调用成员对象的构造函数,调用顺序按照它们在类中声明的顺序。
3.派生类的构造函数体中的内容。
多继承方式下构造函数的执行顺序:
例6-4派生类构造函数举例
#include<
classB1//基类B1,构造函数有参数
B1(inti){cout<
constructingB1"
i<
classB2//基类B2,构造函数有参数
B2(intj){cout<
constructingB2"
j<
classB3//基类B3,构造函数无参数
B3(){cout<
constructingB3*"
publicB2,publicB1,publicB3
public:
//派生类的公有成员
C(inta,intb,intc,intd):
B1(a),memberB2(d),memberB1(c),B2(b)
{}
//派生类的私有对象成员
B1memberB1;
B2memberB2;
B3memberB3;
voidmain()
Cobj(1,2,3,4);
输出结果:
constructingB22
constructingB11
constructingB3*
constructingB13
constructingB24
继承时的析构函数
●析构函数也不被继承,派生类自行声明。
●声明方法与一般(无继承关系时)类的析构函数相同。
●不需要显式地调用基类的析构函数,系统会自动隐式调用。
●析构函数的调用次序与构造函数相反。
例6-5派生类析构函数举例
classB1//基类B1声明
B1(inti)
{cout<
~B1(){cout<
destructingB1"
classB2//基类B2声明
B2(intj)
}
~B2(){cout<
destructingB2"
classB3//基类B3声明
~B3(){cout<
destructingB3"
输出结果:
同名覆盖原则
当派生类与基类中有相同成员时:
●若未强行指名,则通过派生类对象使用的是派生类中的同名成员。
●如要通过派生类对象访问基类中被覆盖的同名成员,应使用基类名限定(:
)。
例6-6多继承同名覆盖举例
classB1//声明基类B1
//外部接口
intnV;
voidfun(){cout<
MemberofB1"
classB2//声明基类B2
MemberofB2"
classD1:
publicB1,publicB2
//同名数据成员
MemberofD1"
}//同名函数成员
{D1d1;
d1.nV=1;
//对象名.成员名标识,访问D1类成员
d1.fun();
d1.B1:
nV=2;
//作用域分辨符标识,访问基类B1成员
fun();
d1.B2:
nV=3;
//作用域分辨符标识,访问基类B2成员
二义性问题
●在多继承时,基类与派生类之间,或基类之间出现同名成员时,将出现访问时的二义性(不确定性)——采用虚函数或支配(同名覆盖)原则来解决。
●当派生类从多个基类派生,而这些基类又从同一个基类派生,则在访问此共同基类中的成员时,将产生二义性——采用虚基类来解决。
二义性问题举例
voidf();
voidg();
二义性的解决方法
●解决方法一:
用类名来限定
c1.A:
f()或c1.B:
f()
●解决方法二:
同名覆盖
在C中声明一个同名成员函数f(),
f()再根据需要调用A:
f()或B:
classB1:
publicB
intb1;
classB2:
intb2;
下面的访问是二义性的:
Cc;
c.b
c.B:
b
下面是正确的:
c.B1:
c.B2:
派生类C的对象的存储结构示意图:
虚基类
●虚基类的引入
–用于有共同基类的场合
●声明
–以virtual修饰说明基类
例:
classB1:
virtualpublicB
●作用
–主要用来解决多继承时可能发生的对同一基类继承多次而产生的二义性问题.
–为最远的派生类提供唯一的基类成员,而不重复产生多次拷贝
●注意:
–在第一级继承时就要将共同基类设计为虚基类。
虚基类举例
classB{private:
virtualpublicB{private:
classC:
publicB1,publicB2{private:
floatd;
下面的访问是正确的:
Ccobj;
cobj.b;
虚基类的派生类对象存储结构示意图:
例6-7虚基类举例
classB0//声明基类B0
MemberofB0"
virtualpublicB0//B0为虚基类,派生B1类
//新增外部接口
intnV1;
classB2:
virtualpublicB0//B0为虚基类派生B2类
intnV2;
publicB1,publicB2//派生类D1声明
intnVd;
voidfund(){cout<
voidmain()//程序主函数
//声明D1类对象d1
d1.nV=2;
//使用直接基类
虚基类及其派生类构造函数
●建立对象时所指定的类称为最(远)派生类。
●虚基类的成员是由最远派生类的构造函数通过调用虚基类的构造函数进行初始化的。
●在整个继承结构中,直接或间接继承虚基类的所有派生类,都必须在构造函数的成员初始化表中给出对虚基类的构造函数的调用。
如果未列出,则表示调用该虚基类的缺省构造函数。
●在建立对象时,只有最远派生类的构造函数调用虚基类的构造函数,该派生类的其它基类对虚基类构造函数的调用被忽略。
有虚基类时的构造函数举例
B0(intn){nV=n;
virtualpublicB0
B1(inta):
B0(a){}
B2(inta):
publicB1,publicB2
D1(inta):
B0(a),B1(a),B2(a){}
voidmain()
D1d1;
赋值兼容原则
●一个公有派生类的对象在使用上可以被当作基类的对象,反之则禁止。
具体表现在:
–派生类的对象可以被赋值给基类对象。
–派生类的对象可以初始化基类的引用。
–指向基类的指针也可以指向派生类。
例6-8赋值兼容规则举例
classB0//基类B0声明
voiddisplay(){cout<
B0:
display()"
}//公有成员函数
publicB0
B1:
publicB1
D1:
voidfun(B0*ptr)
{ptr->
display();
//"
对象指针->
成员名"
voidmain()//主函数
{B0b0;
//声明B0类对象
B1b1;
//声明B1类对象
//声明D1类对象
B0*p;
//声明B0类指针
p=&
b0;
//B0类指针指向B0类对象
fun(p);
b1;
//B0类指针指向B1类对象
d1;
//B0类指针指向D1类对象
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 复习
![提示](https://static.bdocx.com/images/bang_tan.gif)