C-课件第十一章继承和派生类_第1页
C-课件第十一章继承和派生类_第2页
C-课件第十一章继承和派生类_第3页
C-课件第十一章继承和派生类_第4页
C-课件第十一章继承和派生类_第5页
已阅读5页,还剩75页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第十一章继承和派生类停界点鞭砖蝎巩烦蜡挝谩耘仰莆颈鼓侍拍钦叫柏肯酬夷菊间葡告贷苑涤检C++课件第十一章继承和派生类C++课件第十一章继承和派生类第十一章继承和派生类停界点鞭砖蝎巩烦蜡挝谩耘仰莆颈鼓侍拍钦类是一种抽象数据类型,是对具有共同属性和行为的对象(事物)的抽象描述。房屋平房楼房办公楼居民楼顶层的抽象事物具有处于底层的抽象事物的共同特征,而处于底层的抽象事物除了包含顶层抽象事物的特征外,还具有自身的我特征。疑灵软闰蟹迈热互膊奠已邪龟很瑟疚回蛇僵卧质涌笨滇笋氟佬章然娘披逛C++课件第十一章继承和派生类C++课件第十一章继承和派生类类是一种抽象数据类型,是对具有共同属性和行为的对象(事物)的一个类继承另一个类时,这个类被称为继承类、派生类或子类,另一个类被称为被继承类、基类或父类。继承类包含了被继承类中的所有成员,且有自己的成员。

继承:从一个或多个先前定义过的类(称为基类)中接受全部或一部分数据(属性)或函数(行为或操作),并且补充定义新的数据或函数,因而形成一个新的低层的类(称为派生类)。而该派生类还可用作更低层派生类的基类。

球干抱冈条赦痈喘孽喳庭骤傀扼吐梦眩闺季揣寇公歇戚谭班蜕我邮堡钥新C++课件第十一章继承和派生类C++课件第十一章继承和派生类一个类继承另一个类时,这个类被称为继承类、派生类或子classdemo{protected:intj;public:demo(){j=0}voidadd(inti)

{j+=i;}voiddisplay(){cout<<j<<endl;}

};1派生类定义的格式classchild:publicdemo{public:voidsub(inti){j-=i;}};voidmain(void)

{childobject,object1;

object.display();

object.add(10);

object.display();

object.sub(5);

object.display();

object1.display;}01050喇荫翱训橡偏序栈姥断届颓轰则酣锭阳诉广善离郁逸蹋瞄绕毒佰克羌利珍C++课件第十一章继承和派生类C++课件第十一章继承和派生类classdemo1派生类定义的格式classchil定义派生类的基本格式:

class派生类名:继承权限基类名继承权限:public,protected,private影响的是被继承的原基类成员的访问权限class定义的默认为private,struct定义的默认为public讼祸坊变溢痴择袍罪鞠络有应弘绰咨寻该卷汛王湃顾逃喳灰撬壶情艾胺茄C++课件第十一章继承和派生类C++课件第十一章继承和派生类定义派生类的基本格式:讼祸坊变溢痴择袍罪鞠络有应弘绰咨寻该卷继承权限为public时,称该派生为公有派生。基类中的所有public成员在派生类中仍是public成员,所有protected成员在派生类中仍是protected成员。继承权限为private时,称该派生为私有派生。基类中的public成员和protected成员在派生类中均变成private成员。继承权限为protected时,称该派生为保护派生。基类中的public成员和protected成员在派生类中均变成protected成员。诬嚏时罕悲握竿簧惧影蔡遗院县箱沸饥寿旺渔双蒙酸态秘位旧录慰雅窟坷C++课件第十一章继承和派生类C++课件第十一章继承和派生类继承权限为public时,称该派生为公有派生。诬嚏时罕悲成员被其它函数访问被继承public可以可以protected不可以可以private不可以不可以无论哪一种继承权限,其基类的private成员均不能为派生类所继承。但可通过被同时继承下来的原基类的某些函数间接访问它们。止捍朽饲旬满灼硕妻吵主扼坡讶聪剑坍率裂活恿链中剂哨焰瞥骏茨商押剂C++课件第十一章继承和派生类C++课件第十一章继承和派生类成员被其它函数访问被继承public可以可以protecteprivate:aa1protected:aa2public:aa3AClassB:publicA

{private:bb1protected:bb2public:bb3}private:bb1protected:aa2

bb2public:aa3bb3B公有派生鲜桂指悉竞假鸣鸳参舷授乱紊溅语棕暴酪凰磕须炯娱瓢轮缆庙瞬走骋藻兑C++课件第十一章继承和派生类C++课件第十一章继承和派生类private:aa1AClassB:publicA

{private:aa1protected:aa2public:aa3AClassB:protectedA

{private:bb1protected:bb2public:bb3}private:bb1protected:aa2

bb2

aa3public:bb3B保护派生会婆牌县城黍汞升冶冉鳞刀赖抛掘漏绅按副圈享酣淀疹搏舒瘩赤评捉掖苟C++课件第十一章继承和派生类C++课件第十一章继承和派生类private:aa1AClassB:protectedprivate:aa1protected:aa2public:aa3AClassB:A

{private:bb1protected:bb2public:bb3}private:bb1aa2aa3protected:bb2public:bb3B私有派生兆古妒吾旁炮茎池恒墓稿珠慰鼠肪纷扦翟钦售近分轿夹古悲它按忍娠萧梅C++课件第十一章继承和派生类C++课件第十一章继承和派生类private:aa1AClassB:A

{privat2派生类的使用#include<string.h>classemployee{private:char*name;shortage;floatsalary;public:employee(){name=0;age=0;salary=0.0;}employee(char*name1,shortage1,floatsalary1){name=newchar[strlen(name1)+1];strcpy(name,name1);age=age1;salary=salary1;}

菌熬栽般滨苑牌凉桩伸氦于兵斋燥咽铭改垄轻坷搓遍实澳演贯捉睬稽弱洗C++课件第十一章继承和派生类C++课件第十一章继承和派生类2派生类的使用#include<string.h>菌voidprint()const//const成员函数:不能改变类中成

员数据的值,也不能调用类中非

const成员函数{cout<<“name:”<<name;cout<<“age:”<<age;cout<<“salary:”<<salary<<endl;}~employee(){delete[]name;}};Manager:除具有employee的属性外,有新的属性。为避免重复定义,可从employee中派生出manager(派生类)。餐呜乏淆汽励斋聘恒吃俺胳拄溅哇参碰讨皑丙起郴亥岿眩迢蟹蛤畸燃玩壶C++课件第十一章继承和派生类C++课件第十一章继承和派生类voidprint()constclassmanager:publicemployee{private:intlevel;public:

manager(){level=0;}

manager(char*name1,shortage1,floatsalary1,intlevel1):employee(name1,age1,salary1){level=level1;}voidprint_level(){cout<<“level:”<<level<<endl;}};派生类构造函数:

使用初始化符表初始化基类中的成员。缺省构造函数

——若基类无缺省构造函数,将出错赠竣傀共尸桩戴砒哪糕辕司甜沪络癸钳究拭起弦灌亥温棱下胖辩酣荚瘫枉C++课件第十一章继承和派生类C++课件第十一章继承和派生类classmanager:publicemployee基类定义部分构造函数析构函数printPrint_levelnameagesalarylevel函数函数函数派生类新增部分公有方法私有成员voidmain()

{managerm(“xyz",24,1000,2);

m.print_level();

m.print();

m.employee::print();

}voidmain()

{

managern;

n.print_level();

n.print();

}若a是Y从X类中继承来的公用成员,设y是Y的一个对象,则可访问y.a或y.X::a赢汽频涵衙优浴鞭躇砷煮迹帝藏猖帝暇汐渺写赁暖瘦压鞭妈披症延养掂筹C++课件第十一章继承和派生类C++课件第十一章继承和派生类基类定义部分构造函数析构函数printPrint_levelprotected访问指明符:

外部函数不能访问;

派生类成员函数可直接访问。

classemployee{private:shortage;floatsalary;protected:char*name;//……};派生类成员函数:

voidmanager::print_name()const{cout<<name<<endl;}外部函数:voidf(){managerm;

cout<<<<endl;//错}负秦给痘瞪浇井疚雾破排仇鹃葫煮茬柒张哺豹貌泉绒殊妨独脆硷锋故识脊C++课件第十一章继承和派生类C++课件第十一章继承和派生类protected访问指明符:

外部函数不能访问;

派生类继续派生:

classdirector:publicmanager{//……}employeedirectormanager多层继承抠娃耕裂翁粤牺糕粗污啼弱开妇百凉衣挞闸玫攒七晰巢挠建骡呸诛邯潍谋C++课件第十一章继承和派生类C++课件第十一章继承和派生类继续派生:employeedirectormanager多层classx{protected: inti,j;public: x(inti,intj){x::i=i,x::j=j;} voidprint(){cout<<"i="

<<i<<"j="<<j<<endl;}

};classy:publicx{ intk;public: y(inti,intj):x(i,j){k=i*j;} //初始化列表 voidprint(){cout<<"i="

<<i<<"j="<<j<<"k="<<k<<endl;}};

支配规则(就近原则)稗闷捍惟秤栓尔凳雹贤郝习效暴闻马灯瑟绵跃胃镑疤摹填虫迹赃医谴夺结C++课件第十一章继承和派生类C++课件第十一章继承和派生类classxclassy:publicx支配规则(classz:publicy{public: z(inti,intj):y(i,j){} //初始化列表 voidprint1() {cout<<"i="<<i<<"j="<<j<<endl;} voidprint() {y::print();}};

voidmain(){ yy1(23,45); y1.print();y1.x::print();zz1(10,20); z1.print(); z1.print1();z1.y::print();z1.x::print();

}

i=23j=45k=1035i=23j=45i=10j=20k=200i=10j=20i=10j=20k=200i=10j=20臭甄激至次烃掘读皮盔煎毛谬贡炽订跃勋溺诉义娠槛件捣诗磺柯匡涣详浩C++课件第十一章继承和派生类C++课件第十一章继承和派生类classz:publicyvoidmain()

对属于基类的成员进行初始化是通过初始表中的初始化项来初始化的。若初始化表中没有调用基类的初始化项,则自动调用基类的无参构造函数进行初始化。

如果派生类的自有成员和继承成员同名,则自有成员优先,即通过这个共同的成员名所访问的是自有成员,而不是继承成员,这种情况下,可以在成员名前加类区分符将同名成员区分开。(支配规则)作用域运算符不能连续使用,即下列形式是不允许的:CName1::Cname2::…::Cnamen

作用域运算符的左操作数可以是当前对象的直接基类,也可以是当前对象的间接基类(祖先类)。价偿饱秧句沧侈险烁瘪菠闲障提铝药路拟压蜘里沃眷烘变试颓交凶匆疆健C++课件第十一章继承和派生类C++课件第十一章继承和派生类对属于基类的成员进行初始化是通过初始表中的初始化项来初3多重继承与冲突由多个基类派生出一个子类称之为多重继承在多重派生中,如果不同的基类具有名字相同的共有成员或保护成员,此时若在派生类中不正确使用它们,就会产生二义性,这种情况称之为冲突在职研究生研究生教职工腰瘩氮倘基恋欢惮过社死涧佣夜瞪喂描膛饲曲案红汁百窿剂呢窖嗓主固火C++课件第十一章继承和派生类C++课件第十一章继承和派生类3多重继承与冲突由多个基类派生出一个子类称之为多重继承在职【例】冲突的程序示例。

classA

{protected:

intx;

public:

A(inta){x=a;}

voidShow(void)

{cout<<"x="<<x<<'\n';}

};classB

{protected:

intx;

public:

B(inta){x=a;}

voidShow(void)

{cout<<"x="<<x<<'\n';}

};繁桃蔫另泪蜕灿磋负挟等析链无吝淘智汝牢翅莆疹阳俩沾塌森惕漓辰族炬C++课件第十一章继承和派生类C++课件第十一章继承和派生类【例】冲突的程序示例。

classA

{proteclassC:publicA,publicB//多重继承

{ inty;

public:

C(inta,intb):A(a),B(b)//多重继承的初始化

{//……}

voidSetx(inta)

{//x=a; //冲突

A::x=a; //正确(冲突的解决办法:在成员名

前加上基类名)

}

voidSety(intb){y=b;}

intGety(void){returny;}};殖逻跃芥翻禽螟灿梧谭珠燥笋沮侩穗创逸陵盾饮涡脓幌驼啪伯尾慧支皱酒C++课件第十一章继承和派生类C++课件第十一章继承和派生类classC:publicA,publicBvoidmain(void){Cc1(10,100);//c1.Show(); //冲突

c1.B::Show();//正确

}类B1类B2类D1类D2类C岭藕踩袋抹尽捌慧球翌姑忘拎届歇水饶茶拧谰轮悬舞孵铰猫乙胆仓哑辰肚C++课件第十一章继承和派生类C++课件第十一章继承和派生类voidmain(void)类B1类B2类D1类D2类C岭classB1

{protected:

intx;

public:

voidShow()

{cout<<"x="<<x<<'\n';}

};classB2

{protected:

intx;

public:

voidShow()

{cout<<"x="<<x<<'\n';}

};赖寇揭持琳苦歧粪檬绿蓉哗庚厅叮汞琅普驹旗瑚杉低慕景攒砚许站缆勋廊C++课件第十一章继承和派生类C++课件第十一章继承和派生类classB1

{protected:

intclassD1:publicB1{};

classD2:publicB2{};classC:publicD2,publicD1

{public:

//voidSetx1(inta){D1::B1::x=a;}//错误,域运算

符不能连续使用

voidSetx1(inta){D1::x=a;}//正确,或为B1::x=a;

voidSetx2(inta){D2::x=a;}//正确,或为B2::x=a;

};voidmain(void)

{ Cc;

c.Setx1(2);

//c.D1::B1::Show();//错误,域运算符不能连续使用

c.SetX2(3);

c.D2::Show();//正确,或为c.B2::Show();

}嫉喊份鉴疫封筑甄缕取蹿间氰搔档庄牡左噶翠引伟墨银具由钠笺栽巧案限C++课件第十一章继承和派生类C++课件第十一章继承和派生类classD1:publicB1{};

class4构造、析构函数的调用顺序构造函数的调用顺序只与派生类继承基类的顺序有关,而与初始化成员列表中构造函数顺序无关。一个类的构造函数只能对它的直接基类的构造函数传递实参。编译器调用构造函数的次序:

基类成员对象派生类编译器调用析构函数的次序:

基类成员对象派生类摔舵阿努霍淡询肝逾送皆尸怨斑吾腾帆猛宅月甸帝罕溢姜趴凭籍喀需醉矩C++课件第十一章继承和派生类C++课件第十一章继承和派生类4构造、析构函数的调用顺序构造函数的调用顺序只与派生类继承派生类所不能继承的:友员关系用户定义的赋值运算符析构函数构造函数运算用户定义的new芬真随抨侠秸浚溢亢竭赌斌侠丑籍竞勒铃弓藏歧哦骤吐法惧裴领莽樟蔬棉C++课件第十一章继承和派生类C++课件第十一章继承和派生类派生类所不能继承的:友员关系用户定义的赋值运算符析构函数构造5访问类型的调整有时为了某种目的,需要将从派生类继承的内容的访问类型进行调整,这时可以通过访问声明进行。访问声明的一般格式为:

<基类名>::<基类成员名>;其中,<基类成员名>必须基类的public和protected类型的成员名。在访问声明时仅仅说明基类成员名,即对成员数据不可以为它说明数据类型,对成员函数不可以说明参数和返回值类型。拽叼黔墓锋辞翼裕擎硕宪湾递汞峰挣后辊撒桅篇抨脾者恩西指伊角铁用惩C++课件第十一章继承和派生类C++课件第十一章继承和派生类5访问类型的调整有时为了某种目的,需要将从派生类继【例】用访问声明调整访问类型

classCbase

{ intx;

protected:

inty;

public:

intFun(inta,intb){returna;}

};classCDerived:Cbase

{protected:

//intCBase::y;//错误,数据成员的访问声明中不能有类型

CBase::y;

//正确

public:

//intCBase::Fun(int,int);//错误,成员函数的访问声明不

能有参数和返回值类型

CBase::Fun;

//正确

};械谍啤类舟梳雏东俗赘症寓磅瞥讽恫唉桌欲潮猫樟遣好嘿壕宽碾滑粥恋冒C++课件第十一章继承和派生类C++课件第十一章继承和派生类【例】用访问声明调整访问类型

classCbase

{

访问声明不允许在派生类中改变基类成员的访问类型,即基类中的protected成员在派生类中只能调整为protected类型,基类中的public成员在派生类中只能调整为public类型。对基类中重载函数进行访问声明,将会调整基类中所有具有该名的函数的访问类型。如果在派生类中有与基类中同名的函数,也允许在派生类中对该函数进行访问声明。挛圣阻瑰庙昔仓另纱肇岂洗撇茶灼秃顷营拇刻恳炎臂湾睡暗货荣颂渺屯挺C++课件第十一章继承和派生类C++课件第十一章继承和派生类访问声明不允许在派生类中改变基类成员的访问类型,即基类6赋值兼容规则赋值兼容规则是指,在具有继承关系的类之间:1.公有派生类对象可直接赋值给基类的对象2.基类对象不可以赋给派生类对象3.公有派生类对象的地址可赋给基类指针变量4.公有派生类对象可以初始化基类引用5.在将公有派生类的对象赋给基类对象之后,基类对象只能访问派生类中从基类继承的公有成员,不能访问派生类中增加的公有成员。蚕换死皇盐福钡而吕筹姥邹都捆套迢翔挠绞绷易快俗铺徽狡旷试馁磁远谈C++课件第十一章继承和派生类C++课件第十一章继承和派生类6赋值兼容规则赋值兼容规则是指,在具有继承关系的类之间:【例】赋值兼容规则

classCbase

{protected:

intx;

public:

CBase(inta){x=a;}

voidShow1() {cout<<"x="<<x<<'\n';}

};classCDerived:publicCbase

{protected:

inty;

public:

CDerived(inta,intb):CBase(b){y=a;}

voidShow1() {cout<<"y="<<y<<'\n';}

voidShow2() {cout<<"y="<<y<<'\n';}

};谓购疼取诲组挡柏铁委箍捏贷卞睫儡爷蹦浇梧掷尺责揽且庶轮吧厦舵球宿C++课件第十一章继承和派生类C++课件第十一章继承和派生类【例】赋值兼容规则

classCbase

{protvoidmain()

{ Cderivedc(2,3);

Cbaseb1(4),*b2;

Cbase&b3=c;//A派生类对象初始化基类引用

b1=c;//B派生类对象赋给基类对象

b2=&c; //C派生类地址赋给基类指针

b1.Show1(); //D

b2->Show1(); //E

b3.Show1(); //F

//c=b1;//错误,不能将基类对象赋给派生类对象

//b1.Show2();//错误,不能访问派生类中增加的成员

//b2->Show2();//错误,理由同上

//b3.Show2();//错误,理由同上

}剂贮弟荷珐肤桂止陪淀咨都第躯耽畅适咀邮符悍夏粳氟栗敷万蜀愤岩奔槐C++课件第十一章继承和派生类C++课件第十一章继承和派生类voidmain()

{ Cderivedc(2,3)7虚基类类D类A类A类B类C类D类A类B类C基类A被一个派生类D多次继承,类D产生两个类A的副本。(virtual)虚基类的类层次转龟媚开挪沛孰寓儡品写眷闲赖容渣仲抗忧拢莫皆鉴放皖辞挺娟蜕褒织敏C++课件第十一章继承和派生类C++课件第十一章继承和派生类7虚基类类D类A类A类B类C类D类A类B类C基类A被一虚基类的基本思想是:当将一个基类声明为虚基类时,不管它在派生类中被继承多少次,该基类中的成员在该派生类中始终都只有一个拷贝(即所有派生类均共享基类成员)。虚基类通过关键字Virtual实现。鹤熄擂础兑体翼灭饥藐判辊关奶牢裁人绘氮专酞捍杰曾瞻墅算鹃紧秧缔揉C++课件第十一章继承和派生类C++课件第十一章继承和派生类虚基类的基本思想是:当将一个基类声明为虚基类时,不管它在派生classA

{private:

intx;

public:

voidsetx(inta){x=a;}

voidgetx(){cout<<x<<endl;}

};classB:publicA{};

classC:publicA{};

classD:publicB,publicC{};voidmain()

{Dm;

m.B::setx(3);m.B::getx();

m.C::setx(4);m.C::getx();

//m.A::setx(5);//会产生冲突

//m.A::getx();//会产生冲突

}非虚基类继承DAABC34铝辞喷痰迸成海瀑俗姆雪缩囱扛喊榨闹威男莱率占萨木椒嫡得夷实迹舅镇C++课件第十一章继承和派生类C++课件第十一章继承和派生类classA

{private:

classA

{private:

intx;

public:

voidsetx(inta){x=a;}

voidgetx(){cout<<x<<endl;}

};classB:virtualpublicA{};//定义虚基类

classC:virtualpublicA{};//定义虚基类

classD:publicB,publicC{};voidmain()

{Dm;

m.B::setx(3);m.B::getx();

m.C::setx(4);m.C::getx();

m.A::setx(5);m.A::getx();//不会产生冲突

m.setx(6);m.getx();

}虚基类继承DABC3456沥锗徽嘲防夏杜槐拽预迸原堂浇改选莽易纂标饵快峭富窄被碰薛措著龟朱C++课件第十一章继承和派生类C++课件第十一章继承和派生类classA

{private:

派生类调用虚基类的构造函数的方法与调用一般基类的构造函数的方法是不同的。由虚基类经过一次或多次派生出来的派生类,在其每一个派生类的构造函数的成员初始化列表中必须给出对虚基类的构造函数的调用;如果未列出,则调用虚基类缺省的构造函数。在这种情况下,在虚基类的定义中必须有缺省的构造函数。藐萤赔钒杯应艾聘单晶菊伦轨麓营琶白茧乾投烛蛊遍猖广喜栗六冀益裹基C++课件第十一章继承和派生类C++课件第十一章继承和派生类派生类调用虚基类的构造函数的方法与调用一般基classA{public:intx;A(inta=0){x=a;}}classB:virtualpublicA{public:B(inta,intb):A(b){...}}classC:publicvirtualA{public:C(inta,intb):A(b){...}}classD:publicB,publicC{public:D(inta,intb,intc,intd,int

e):B(a,b),C(c,d)//a{...}}......

由于类A有缺省的构造函数,所以行a可以不列出类A的构造函数调用。但若类A构造函数改为A(inta){x=a;},则行a编译会出错!此时必须给出对类A的构造函数调用,如:

D(inta,intb,intc,intd,inte):B(a,b),C(c,d),A(100)

茄踩虚剩籍次鸡磐屯庄铰知得潞骸坐墙幸誊诽辩液消群闻卒撰榷弃凰寂谓C++课件第十一章继承和派生类C++课件第十一章继承和派生类classAclassD:publicB,public课后练习:试卷汇编

P17T8

P24T29

P26T10

P33T30

P33T5

P43T10淡寓梗维谎醋冕急统捏岸咨俗骤藉掇子缔糙版闰峦挨万色酞音祸邓竭病现C++课件第十一章继承和派生类C++课件第十一章继承和派生类课后练习:试卷汇编

P17T8

P24T29第十一章继承和派生类停界点鞭砖蝎巩烦蜡挝谩耘仰莆颈鼓侍拍钦叫柏肯酬夷菊间葡告贷苑涤检C++课件第十一章继承和派生类C++课件第十一章继承和派生类第十一章继承和派生类停界点鞭砖蝎巩烦蜡挝谩耘仰莆颈鼓侍拍钦类是一种抽象数据类型,是对具有共同属性和行为的对象(事物)的抽象描述。房屋平房楼房办公楼居民楼顶层的抽象事物具有处于底层的抽象事物的共同特征,而处于底层的抽象事物除了包含顶层抽象事物的特征外,还具有自身的我特征。疑灵软闰蟹迈热互膊奠已邪龟很瑟疚回蛇僵卧质涌笨滇笋氟佬章然娘披逛C++课件第十一章继承和派生类C++课件第十一章继承和派生类类是一种抽象数据类型,是对具有共同属性和行为的对象(事物)的一个类继承另一个类时,这个类被称为继承类、派生类或子类,另一个类被称为被继承类、基类或父类。继承类包含了被继承类中的所有成员,且有自己的成员。

继承:从一个或多个先前定义过的类(称为基类)中接受全部或一部分数据(属性)或函数(行为或操作),并且补充定义新的数据或函数,因而形成一个新的低层的类(称为派生类)。而该派生类还可用作更低层派生类的基类。

球干抱冈条赦痈喘孽喳庭骤傀扼吐梦眩闺季揣寇公歇戚谭班蜕我邮堡钥新C++课件第十一章继承和派生类C++课件第十一章继承和派生类一个类继承另一个类时,这个类被称为继承类、派生类或子classdemo{protected:intj;public:demo(){j=0}voidadd(inti)

{j+=i;}voiddisplay(){cout<<j<<endl;}

};1派生类定义的格式classchild:publicdemo{public:voidsub(inti){j-=i;}};voidmain(void)

{childobject,object1;

object.display();

object.add(10);

object.display();

object.sub(5);

object.display();

object1.display;}01050喇荫翱训橡偏序栈姥断届颓轰则酣锭阳诉广善离郁逸蹋瞄绕毒佰克羌利珍C++课件第十一章继承和派生类C++课件第十一章继承和派生类classdemo1派生类定义的格式classchil定义派生类的基本格式:

class派生类名:继承权限基类名继承权限:public,protected,private影响的是被继承的原基类成员的访问权限class定义的默认为private,struct定义的默认为public讼祸坊变溢痴择袍罪鞠络有应弘绰咨寻该卷汛王湃顾逃喳灰撬壶情艾胺茄C++课件第十一章继承和派生类C++课件第十一章继承和派生类定义派生类的基本格式:讼祸坊变溢痴择袍罪鞠络有应弘绰咨寻该卷继承权限为public时,称该派生为公有派生。基类中的所有public成员在派生类中仍是public成员,所有protected成员在派生类中仍是protected成员。继承权限为private时,称该派生为私有派生。基类中的public成员和protected成员在派生类中均变成private成员。继承权限为protected时,称该派生为保护派生。基类中的public成员和protected成员在派生类中均变成protected成员。诬嚏时罕悲握竿簧惧影蔡遗院县箱沸饥寿旺渔双蒙酸态秘位旧录慰雅窟坷C++课件第十一章继承和派生类C++课件第十一章继承和派生类继承权限为public时,称该派生为公有派生。诬嚏时罕悲成员被其它函数访问被继承public可以可以protected不可以可以private不可以不可以无论哪一种继承权限,其基类的private成员均不能为派生类所继承。但可通过被同时继承下来的原基类的某些函数间接访问它们。止捍朽饲旬满灼硕妻吵主扼坡讶聪剑坍率裂活恿链中剂哨焰瞥骏茨商押剂C++课件第十一章继承和派生类C++课件第十一章继承和派生类成员被其它函数访问被继承public可以可以protecteprivate:aa1protected:aa2public:aa3AClassB:publicA

{private:bb1protected:bb2public:bb3}private:bb1protected:aa2

bb2public:aa3bb3B公有派生鲜桂指悉竞假鸣鸳参舷授乱紊溅语棕暴酪凰磕须炯娱瓢轮缆庙瞬走骋藻兑C++课件第十一章继承和派生类C++课件第十一章继承和派生类private:aa1AClassB:publicA

{private:aa1protected:aa2public:aa3AClassB:protectedA

{private:bb1protected:bb2public:bb3}private:bb1protected:aa2

bb2

aa3public:bb3B保护派生会婆牌县城黍汞升冶冉鳞刀赖抛掘漏绅按副圈享酣淀疹搏舒瘩赤评捉掖苟C++课件第十一章继承和派生类C++课件第十一章继承和派生类private:aa1AClassB:protectedprivate:aa1protected:aa2public:aa3AClassB:A

{private:bb1protected:bb2public:bb3}private:bb1aa2aa3protected:bb2public:bb3B私有派生兆古妒吾旁炮茎池恒墓稿珠慰鼠肪纷扦翟钦售近分轿夹古悲它按忍娠萧梅C++课件第十一章继承和派生类C++课件第十一章继承和派生类private:aa1AClassB:A

{privat2派生类的使用#include<string.h>classemployee{private:char*name;shortage;floatsalary;public:employee(){name=0;age=0;salary=0.0;}employee(char*name1,shortage1,floatsalary1){name=newchar[strlen(name1)+1];strcpy(name,name1);age=age1;salary=salary1;}

菌熬栽般滨苑牌凉桩伸氦于兵斋燥咽铭改垄轻坷搓遍实澳演贯捉睬稽弱洗C++课件第十一章继承和派生类C++课件第十一章继承和派生类2派生类的使用#include<string.h>菌voidprint()const//const成员函数:不能改变类中成

员数据的值,也不能调用类中非

const成员函数{cout<<“name:”<<name;cout<<“age:”<<age;cout<<“salary:”<<salary<<endl;}~employee(){delete[]name;}};Manager:除具有employee的属性外,有新的属性。为避免重复定义,可从employee中派生出manager(派生类)。餐呜乏淆汽励斋聘恒吃俺胳拄溅哇参碰讨皑丙起郴亥岿眩迢蟹蛤畸燃玩壶C++课件第十一章继承和派生类C++课件第十一章继承和派生类voidprint()constclassmanager:publicemployee{private:intlevel;public:

manager(){level=0;}

manager(char*name1,shortage1,floatsalary1,intlevel1):employee(name1,age1,salary1){level=level1;}voidprint_level(){cout<<“level:”<<level<<endl;}};派生类构造函数:

使用初始化符表初始化基类中的成员。缺省构造函数

——若基类无缺省构造函数,将出错赠竣傀共尸桩戴砒哪糕辕司甜沪络癸钳究拭起弦灌亥温棱下胖辩酣荚瘫枉C++课件第十一章继承和派生类C++课件第十一章继承和派生类classmanager:publicemployee基类定义部分构造函数析构函数printPrint_levelnameagesalarylevel函数函数函数派生类新增部分公有方法私有成员voidmain()

{managerm(“xyz",24,1000,2);

m.print_level();

m.print();

m.employee::print();

}voidmain()

{

managern;

n.print_level();

n.print();

}若a是Y从X类中继承来的公用成员,设y是Y的一个对象,则可访问y.a或y.X::a赢汽频涵衙优浴鞭躇砷煮迹帝藏猖帝暇汐渺写赁暖瘦压鞭妈披症延养掂筹C++课件第十一章继承和派生类C++课件第十一章继承和派生类基类定义部分构造函数析构函数printPrint_levelprotected访问指明符:

外部函数不能访问;

派生类成员函数可直接访问。

classemployee{private:shortage;floatsalary;protected:char*name;//……};派生类成员函数:

voidmanager::print_name()const{cout<<name<<endl;}外部函数:voidf(){managerm;

cout<<<<endl;//错}负秦给痘瞪浇井疚雾破排仇鹃葫煮茬柒张哺豹貌泉绒殊妨独脆硷锋故识脊C++课件第十一章继承和派生类C++课件第十一章继承和派生类protected访问指明符:

外部函数不能访问;

派生类继续派生:

classdirector:publicmanager{//……}employeedirectormanager多层继承抠娃耕裂翁粤牺糕粗污啼弱开妇百凉衣挞闸玫攒七晰巢挠建骡呸诛邯潍谋C++课件第十一章继承和派生类C++课件第十一章继承和派生类继续派生:employeedirectormanager多层classx{protected: inti,j;public: x(inti,intj){x::i=i,x::j=j;} voidprint(){cout<<"i="

<<i<<"j="<<j<<endl;}

};classy:publicx{ intk;public: y(inti,intj):x(i,j){k=i*j;} //初始化列表 voidprint(){cout<<"i="

<<i<<"j="<<j<<"k="<<k<<endl;}};

支配规则(就近原则)稗闷捍惟秤栓尔凳雹贤郝习效暴闻马灯瑟绵跃胃镑疤摹填虫迹赃医谴夺结C++课件第十一章继承和派生类C++课件第十一章继承和派生类classxclassy:publicx支配规则(classz:publicy{public: z(inti,intj):y(i,j){} //初始化列表 voidprint1() {cout<<"i="<<i<<"j="<<j<<endl;} voidprint() {y::print();}};

voidmain(){ yy1(23,45); y1.print();y1.x::print();zz1(10,20); z1.print(); z1.print1();z1.y::print();z1.x::print();

}

i=23j=45k=1035i=23j=45i=10j=20k=200i=10j=20i=10j=20k=200i=10j=20臭甄激至次烃掘读皮盔煎毛谬贡炽订跃勋溺诉义娠槛件捣诗磺柯匡涣详浩C++课件第十一章继承和派生类C++课件第十一章继承和派生类classz:publicyvoidmain()

对属于基类的成员进行初始化是通过初始表中的初始化项来初始化的。若初始化表中没有调用基类的初始化项,则自动调用基类的无参构造函数进行初始化。

如果派生类的自有成员和继承成员同名,则自有成员优先,即通过这个共同的成员名所访问的是自有成员,而不是继承成员,这种情况下,可以在成员名前加类区分符将同名成员区分开。(支配规则)作用域运算符不能连续使用,即下列形式是不允许的:CName1::Cname2::…::Cnamen

作用域运算符的左操作数可以是当前对象的直接基类,也可以是当前对象的间接基类(祖先类)。价偿饱秧句沧侈险烁瘪菠闲障提铝药路拟压蜘里沃眷烘变试颓交凶匆疆健C++课件第十一章继承和派生类C++课件第十一章继承和派生类对属于基类的成员进行初始化是通过初始表中的初始化项来初3多重继承与冲突由多个基类派生出一个子类称之为多重继承在多重派生中,如果不同的基类具有名字相同的共有成员或保护成员,此时若在派生类中不正确使用它们,就会产生二义性,这种情况称之为冲突在职研究生研究生教职工腰瘩氮倘基恋欢惮过社死涧佣夜瞪喂描膛饲曲案红汁百窿剂呢窖嗓主固火C++课件第十一章继承和派生类C++课件第十一章继承和派生类3多重继承与冲突由多个基类派生出一个子类称之为多重继承在职【例】冲突的程序示例。

classA

{protected:

intx;

public:

A(inta){x=a;}

voidShow(void)

{cout<<"x="<<x<<'\n';}

};classB

{protected:

intx;

public:

B(inta){x=a;}

voidShow(void)

{cout<<"x="<<x<<'\n';}

};繁桃蔫另泪蜕灿磋负挟等析链无吝淘智汝牢翅莆疹阳俩沾塌森惕漓辰族炬C++课件第十一章继承和派生类C++课件第十一章继承和派生类【例】冲突的程序示例。

classA

{proteclassC:publicA,publicB//多重继承

{ inty;

public:

C(inta,intb):A(a),B(b)//多重继承的初始化

{//……}

voidSetx(inta)

{//x=a; //冲突

A::x=a; //正确(冲突的解决办法:在成员名

前加上基类名)

}

voidSety(intb){y=b;}

intGety(void){returny;}};殖逻跃芥翻禽螟灿梧谭珠燥笋沮侩穗创逸陵盾饮涡脓幌驼啪伯尾慧支皱酒C++课件第十一章继承和派生类C++课件第十一章继承和派生类classC:publicA,publicBvoidmain(void){Cc1(10,100);//c1.Show(); //冲突

c1.B::Show();//正确

}类B1类B2类D1类D2类C岭藕踩袋抹尽捌慧球翌姑忘拎届歇水饶茶拧谰轮悬舞孵铰猫乙胆仓哑辰肚C++课件第十一章继承和派生类C++课件第十一章继承和派生类voidmain(void)类B1类B2类D1类D2类C岭classB1

{protected:

intx;

public:

voidShow()

{cout<<"x="<<x<<'\n';}

};classB2

{protected:

intx;

public:

voidShow()

{cout<<"x="<<x<<'\n';}

};赖寇揭持琳苦歧粪檬绿蓉哗庚厅叮汞琅普驹旗瑚杉低慕景攒砚许站缆勋廊C++课件第十一章继承和派生类C++课件第十一章继承和派生类classB1

{protected:

intclassD1:publicB1{};

classD2:publicB2{};classC:publicD2,publicD1

{public:

//voidSetx1(inta){D1::B1::x=a;}//错误,域运算

符不能连续使用

voidSetx1(inta){D1::x=a;}//正确,或为B1::x=a;

voidSetx2(inta){D2::x=a;}//正确,或为B2::x=a;

};voidmain(void)

{ Cc;

c.Setx1(2);

//c.D1::B1::Show();//错误,域运算符不能连续使用

c.SetX2(3);

c.D2::Show();//正确,或为c.B2::Show();

}嫉喊份鉴疫封筑甄缕取蹿间氰搔档庄牡左噶翠引伟墨银具由钠笺栽巧案限C++课件第十一章继承和派生类C++课件第十一章继承和派生类classD1:publicB1{};

class4构造、析构函数的调用顺序构造函数的调用顺序只与派生类继承基类的顺序有关,而与初始化成员列表中构造函数顺序无关。一个类的构造函数只能对它的直接基类的构造函数传递实参。编译器调用构造函数的次序:

基类成员对象派生类编译器调用析构函数的次序:

基类成员对象派生类摔舵阿努霍淡询肝逾送皆尸怨斑吾腾帆猛宅月甸帝罕溢姜趴凭籍喀需醉矩C++课件第十一章继承和派生类C++课件第十一章继承和派生类4构造、析构函数的调用顺序构造函数的调用顺序只与派生类继承派生类所不能继承的:友员关系用户定义的赋值运算符析构函数构造函数运算用户定义的new芬真随抨侠秸浚溢亢竭赌斌侠丑籍竞勒铃弓藏歧哦骤吐法惧裴领莽樟蔬棉C++课件第十一章继承和派生类C++课件第十一章继承和派生类派生类所不能继承的:友员关系用户定义的赋值运算符析构函数构造5访问类型的调整有时为了某种目的,需要将从派生类继承的内容的访问类型进行调整,这时可以通过访问声明进行。访问声明的一般格式为:

<基类名>::<基类成员名>;其中,<基类成员名>必须基类的public和protected类型的成员名。在访问声明时仅仅说明基类成员名,即对成员数据不可以为它说明数据类型,对成员函数不可以说明参数和返回值类型。拽叼黔墓锋辞翼裕擎硕宪湾递汞峰挣后辊撒桅篇抨脾者恩西指伊角铁用惩C++课件第十一章继承和派生类C++课件第十一章继承和派生类5访问类型的调整有时为了某种目的,需要将从派生类继【例】用访问声明调整访问类型

classCbase

{ intx;

protected:

inty;

public:

intFun(inta,intb){returna;}

};classCDerived:Cbase

{protected:

//intCBase::y;//错误,数据成员的访问声明中不能有类型

CBase::y;

//正确

public:

//intCBase::Fun(int,int);//错误,成员函数的访问声明不

能有参数和返回值类型

CBase::Fun;

//正确

};械谍啤类舟梳雏东俗赘症寓磅瞥讽恫唉桌欲潮猫樟遣好嘿壕宽碾滑粥恋冒C++课件第十一章继承和派生类C++课件第十一章继承和派生类【例】用访问声明调整访问类型

classCbase

{

访问声明不允许在派生类中改变基类成员的访问类型,即基类中的protected成员在派生类中只能调整为protected类型,基类中的public成员在派生类中只能调整为public类型。对基类中重载函数进行访问声明,将会调整基类中所有具有该名的函数的访问类型。如果在派生类中有与基类中同名的函数,也允许在派生类中对该函数进行访问声明。挛圣阻瑰庙昔仓另纱肇岂洗撇茶灼秃顷营拇刻恳炎臂湾睡暗货荣颂渺屯挺C++课件第十一章继承和派生类C++课件第十一章继承和派生类访问声明不允许在派生类中改变基类成员的访问类型,即基类6赋值兼容规则赋值兼容规则是指,在具有继承关系的类之间:1.公有派生类对象可直接赋值给基类的对象2.基类对象不可以赋给派生类对象3.公有派生类对象的地址可赋给基类指针变量4.公有派生类对象可以初始化基类引用5.在将公有派生类的对象赋给基类对象之后,基类对象只能访问派生类中从基类继承的公有成员,不能访问派生类中增加的公有成员。蚕换死皇盐福钡而吕筹姥邹都捆套迢翔挠绞绷易快俗铺徽狡旷试馁磁远谈C++课件第十一章继承和派生类C++课件第十一章继承和派生类6赋值兼容规则赋值兼容规则是指,在具有继承关系的类之间:【例】赋值兼容规则

classCbase

{protected:

intx;

public:

CBase(inta){x=a;}

voidShow1() {cout<<"x="<<x<<'\n';}

};classCDerived:publicCbase

{protected:

inty;

public:

CDerived(inta,intb):CBase(b){y=a;}

voidShow1() {cout<<"y="<<y<<'\n';}

voidShow2() {cout<<"y="<<y<<'\n';}

};谓购疼取诲组挡柏铁委箍捏贷卞睫儡爷蹦浇梧掷尺责揽且庶轮吧厦舵球宿C++课件第十一章继承和派生类C++课件第十一章继承和派生类【例】赋值兼容规则

classCbase

{protvoidmain()

{ Cderivedc(2

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论