继承与派生2
二级C++类的继承与派生:派生类的构造
1、派⽣类的构造函数:派⽣类的对象的数据结构是由基类中说明的数据成员和派⽣类中说明的数据成员共同构成。
构造函数不能被继承,因此派⽣类的构造函数必须通过调⽤基类的构造函数来初始化基类对象。
所以在定义派⽣类的构造函数时除了对⾃⼰的数据成员进⾏初始化外,还必须负责调⽤基类构造函数使基类的数据成员得以初始化。
如果派⽣类中还有⼦类对象,还应包含对⼦类对象初始化的构造函数。
• ⼀般格式:< 派⽣类名 > ( < 派⽣类构造函数总参数表 > ): < 基类构造函数 >(< 参数表 1>),< ⼦对象名 >(< 参数表 2>){< 派⽣类汇总数据成员初始化 >};• 派⽣类构造函数的调⽤顺序:• 基类的构造函数• ⼦对象类的构造函数• 派⽣类的构造函数例如:分析下列程序的输出结果:#includeclass A{public:A(){a=0;cout<<”A's default constructor called.\n”;}A(int I){a=I;cout<<”A's constructor called.\n”;}~A(){cout<<”A's destructor called.\n”;}void Print(){ cout<int Geta(){return a;}private:int a;};class B:public A{public:B(){b=0;cout<<”B's default constructor called.\n”;}B(int I,int j,int k);~B(){cout<<”B's destructor called.\n”;}void Print();Private:int b;A aa;};B::B(int I,int j,int k):A(i),aa(j){b=k;cout<<”B's constructor called.\n”;}void B::Print(){A::Print();cout<}void main(){B bb[2];bb[0]=B(1,2,5); // 注:给已建⽴的两个对象赋值,系统要建⽴两个bb[1]=B(3,4,7); 匿名对象,通过构造函数对它初始化,并将for (int I=0;I<2;I++) 其赋值给已定义的左值对象,再调⽤析构bb[I].Print(); 函数将匿名对象删除。
继承与派生类PPT演示课件
7.1 基本概念 7.2 派生类的三种继承方式 *7.3 多 重 继 承 与虚基类 习题
1
7.1 基本概念
1、继承与派生
继承是面向对象语言提供的一个重要机制,它在类与类之 间建立了层次关系。首先从下面的实例当中体会继承的概念。
class Box
{
private :
int width,height;
{…
};//同上
10
void main( )
{
ColorBox ob1;
ob1.SetWidth(1);
ob1.SetHeight(2);
ob1.SetColor(3);
ColorBox ob2;
ob2.Width = 1 ; //非法
ob2.color = 3; //×
}
如果在ColorBox内有另外一个成员函数,它能否
12
3、保护成员
用protected说明的成员称为保护成员,保护成员的访问 权限介于私有和公有之间。其规则为:
派生类的成员函数可以访问基类的保护成员,但是在基 类和派生类之外,程序不能访问类的保护成员。
class Box { protected :
int width,height; };
13
class ColorBox :public Box { private :
class Box
{
private :
int width,height;
public:
void SetWidth(int w) { width = w;}
void SetHeight(int h) {height = h;}
};
//同上
继承与派生类
扩充和完善旧的程序设计以适应新的需求 (克服了传统程序设计方法对编写出来的程 序无法重复使用) 规范子类行为 为了降低代码冗余
• 以上介绍的是最简单的情况: 一个派生类只
从一个基类派生,这称为单继承。
• 一。一个派生类有两个或多
个基类的称为多重继承,这种继承关系所形
私有基类在派生类中访问属性
私有基类的成员 私有派生类中的访问属性
private public protected
private private
只继承实现,不继承接口
class Student1: private Student//用私有继承方式声明派生类Student1 {public: void display_1( ) //输出两个数据成员的值 {cout<<″age: ″<<age<<endl; //引用派生类的私有成员,正确 cout<<″address: ″<<addr<<endl;} //引用派生类的私有成员,正 确 private: int age; string addr; }; int main( ) {Student1 stud1;//定义一个Student1类的对象stud1 stud1.display(); //错误,私有基类的公用成员函数在派生类中是私有函数 stud1.display_1( );//正确。Display_1函数是Student1类的公用函数 stud1.age=18; //错误。外界不能引用派生类的私有成员 return 0;}
SuperMan sm; sm.Run(); sm.Jump();
//生命 //魔力 //动作-跑步 //动作-跳
派生类就是在 虽然你没有定义 现在我们需要一个新 就这么简单 的类 SuperMan , Superman 的Run,超人。 但 基类的基础上构建的 多麻烦啊 像 HP, MP, Run 之类 类, 可以节约很多代 是由于继承的原因 , 还需要重新定义一个 只要继承就好了! 的编译器会偷偷帮你 码。 自动包含这个 全新的类 Super , 加上 生命, 加上~ 比如, 魔力 函数 —— 跑, 跳之类的吗?
第11讲-继承与派生(2)上课讲义
Teacher(nam,a,t),Student(nam,s,sco),wage(w) { }
void show( ) //输出研究生的有关数据
{cout<<″name:″<<name<<endl;
cout<<″age:″<<age<<endl;
cout<<″sex:″<<sex<<endl;
cout<<″score:″<<score<<endl;
要细致考虑其数据成员,尽量减少数据冗余。
2020/6/28
12
(3)多重继承引起的二义性问题
这些重复的数据或者同名的成员使用不当,则:会产 生的二义性(ambiguous)问题。
方法:在单继承的基础上,依次列出多个基类。
比如: 如果已声明了类A、类B和类C,可以声明多重继承的
派生类D: class D:public A, private B, protected C {类D新增加的成员}
D按不同的继承方式的规则继承A,B,C的属性,确定各 基类的成员在派生类中的访问权限。
2020/6/28
第11讲-继承与派生(2)
第11讲 继承与派生
11.2 授课要求
(1)理解多重继承的含义、定义方法和实现;
(2)理解虚基类及其作用。
2020/6/28
2
第11讲 继承与派生
11.3 授课重点 1.重点是多重继承和派生类的应用。
11.4 授课难点 1.难点是派生类的应用。
2020/6/28
3
1.多重继承
些数据。
2020/6/28
继承与派生课件
继承与派生
派生类
3
继承与派生问题举例
类
的
动物
继
承
与
派
猴子
猫猫科
鸟
生
狮子
虎
猎豹
继承与派生
4
继承与派生问题举例
类
的 继
几 何形状
承
与
派
生
圆
矩形
继承与派生
5
继承与派生问题举例
类 的 继
承 与 派 兼职技术人员
生
雇员 管理人员
销售经理
继承与派生
单继承
销售人员
多继承
6
类的继承与派生
• 保持已有类的特性而构造新类的过程称为继承。 • 在已有类的基础上新增自己的特性而产生新类的过程称为派生。 • 被继承的已有类称为基类(或父类)。 • 派生出的新类称为派生类(或子类)。
float getX() const { return x; }
员
float getY() const { return y; }
private:
//私有数据成员
的 访 问 控 制
派
float x, y;
};
生
class Rectangle: public Point {
//派生类定义部分
类
public:
继承与派生
7
继承与派生的目的
类 • 继承的的目的:实现代码重用。 • 派生的继 承目的:当新的问题出现,原有程序无法解决(或不能完全 解决)与时,需要对原有程序进行改造。
派 生
继承与派生
8
派生类的声明
类
的 class 派生类名:继承方式1 基类名1, 继承方式2
继承与派生类答案
继承与派生类知识要点1.掌握继承和派生的定义,派生类的定义方法。
(1)掌握继承的两种类型:单继承和多继承。
(2)掌握private,public,protected三种继承方式的特点。
继承方式决定了基类中的成员在派生类中的属性。
三种继承方式的共同点:基类的private成员在派生类中不可见。
区别:对于私有继承,基类的public、protected成员在派生类中作为private成员;对于公有继承,基类的public、protected成员在派生类中访问属性不变;对于保护继承,基类的public、protected成员在派生类中作为protected成员。
(3)掌握派生类中的构造函数和析构函数的使用。
基类的构造函数和析构函数不能继承,所以必要时在派生类中定义自己的构造函数和析构函数。
派生列的构造函数完成基类中新增数据成员和基类数据成员的初始化,基类数据成员的初始化通过基类构造函数来实现。
(4)掌握派生类的同名覆盖规则。
(5)掌握赋值兼容规则。
基类对象可以使用公有派生类对象来代替,包括:派生类对象可以赋值给基类对象;派生类对象可以初始化基类对象的引用;基类类型指针可以指向派生类对象。
2.掌握多重继承的概念、定义方法、多重继承派生类构造函数的执行顺序。
派生类构造函数的执行顺序是先执行所有基类的构造函数(顺序按照定义派生类时指定的各基类顺序),在执行对象成员所在类的构造函数(顺序按照他们在类中的声明顺序),最后执行派生类构造函数体中的内容。
3.掌握虚基类的概念和定义方法。
在多重继承中,如果多条继承路径上有一个公共的基类,则在这些路径的汇合点上的派生类会产生来自不同路径的公共基类的多个拷贝,如果用virtual把公共基类定义成虚基类,则只会保留公共基类的一个拷贝。
典型例题分析与解答例题1:下列对派生类的描述中,()是错误的。
A.一个派生类可以作为另一个派生类的基类B.派生类至少有一个基类C.派生类的成员除了它自己的成员外,还包含了它的基类成员D.派生类中继承的基类成员的访问权限到派生类保持不变答案:D分析:一个派生类可以作为另一个派生类的基类。
继承和派生——类与类之间的关系、继承的基本概念、继承的方式、继承中的构造和析构
继承和派⽣——类与类之间的关系、继承的基本概念、继承的⽅式、继承中的构造和析构1、类与类之间的关系 has-A,uses-A 和 is-A has-A 包含关系,⽤以描述⼀个类由多个“部件类”构成。
实现has-A关系⽤类成员表⽰,即⼀个类中的数据成员是另⼀种已经定义的类。
uses-A ⼀个类部分地使⽤另⼀个类。
通过类之间成员函数的相互联系,定义友员或对象参数传递实现。
is-A 机制称为“继承”。
关系具有传递性,不具有对称性。
class A{public:void funcA(){}int a;};//类B拥有类A的成员变量,B has A,类B 依赖于类Aclass B{public:void funcB(){}A a;};//类C的成员⽅法需要类A的形参,C use A,类C 依赖于类Aclass C{public:void funcC(A *a){}void funcCC(){}};//类D继承于类A, 类D如果是继承类A,类D is 类A,类C 继承于类A,耦合度很⾼class D:public A{public:void funcD(){cout << a << endl;}};2、继承的基本概念 类的继承,是新的类从已有类那⾥得到已有的特性,或从已有类产⽣新类的过程就是类的派⽣。
原有的类称为基类或⽗类,产⽣的新类称为派⽣类或⼦类。
派⽣与继承,是同⼀种意义两种称谓。
is-A 的关系。
派⽣类的⽣成 派⽣类中的成员,包含两⼤部分,⼀类是从基类继承过来的,⼀类是⾃⼰增加的成员。
从基类继承过过来的表现其共性,⽽新增的成员体现了其个性。
⼏点说明:1,全盘接收,除了构造器与析构器。
基类有可能会造成派⽣类的成员冗余,所以说基类是需设计的。
2,派⽣类有了⾃⼰的个性,使派⽣类有了意义。
只能在当前类中访问的成员设置为private3、只能在当前类和⼦类中访问的成员设置为protected,protected成员的访问权限介于public和private之间。
继承和派生ppt课件
public
{ private : < 私有成员> ; public :
< 公有成员> ; protected : < 被保护成员> ;
}
, public
例: 11-4
class A
{protected :
//保护成员
int w;
public :
void Setw(int a) {w=a;}
int Getw(){return w;}
int Getby() {return Gety();}
int Getz() {return z;}
int Sum() {return(z+x+y);}
};
void main()
{ D d;
d.Setbase(1,2);
//对于外部程序,
它是私有的, 成员不能直接访问
d.Setz(3);
cout<<"x="<<d.Getbx()<<endl;
程序: class B { int x,y;
public : void Setx(int a) {x=a;} void Sety(int b) {y=b;} int Getx(){return x;} int Gety(){return y;}
};
class D: public B { int z; public: void Setz(int c) {z=c;} int Getz(){ return z;} int Sum() {return(Getx()+Gety()+Getz());} };
#include "iostream.h"
继承与派生——精选推荐
继承与派⽣继承与派⽣概述:继承与派⽣是同⼀个过程从不同的⾓度看:保持已有类的特性⽽构成新类的过程称为继承在已有类的基础上新增⾃⼰的特性⽽产⽣新类的过程称为派⽣被继承的已有类成为基类(⽗类)base class派⽣出的新类称为派⽣类(⼦类)derived class直接参与派⽣出某类的基类成为直接基类基类的基类甚⾄更⾼层的基类称为间接基类继承的⽬的:实现设计与代码的重⽤,充分利⽤原有的类派⽣的⽬的:当新的问题出现,原有程序⽆法解决,需要对原有程序进⾏改造单继承时派⽣类的定义: class 派⽣类名:继承⽅式基类名{成员声明;}例⼦:class Derived: public Base{public:Derived();~Derived();};多继承时派⽣类的定义:class 派⽣类名:继承⽅式1 基类名1,继承⽅式2 基类名2,。
{成员声明;};例⼦:class Derived: public Base1, private Base 2{public:Derived();~Derived();};派⽣类的构成:吸收基类的成员,(默认情况下,派⽣类包含全部基类中除了构造函数之外的所有成员,C++11规定可以使⽤using语句继承基类构造函数)改造基类成员,(如果派⽣类中声明了⼀个和某基类成员同名的新成员,派⽣的新成员就隐藏或覆盖了外层同名成员)添加新的成员继承⽅式简介:三种继承⽅式:公有(public ),私有(private),保护继承(protected)重点写⼀下保护成员:在派⽣类中可以作为public,在基类中类似private。
(也就是说,如果想要把基类中的私有成员给派⽣类⽤,但是却⼜不想将此成员作为public成员,可以设定为protected成员,这样可以达到派⽣类可以访问的效果)私有继承:将除了私有成员的其他成员转换成派⽣类的私有成员派⽣类的构造函数:派⽣类新增成员:派⽣类定义构造函数初始化;继承来的成员:⾃动调⽤基类构造函数进⾏初始化;派⽣类的构造函数需要给基类的构造函数传递参数。
第3讲--继承与派生
计算机高级语言(C++)中国地质大学(武汉)计算机学院本章主要内容☐3.1类的继承与派生☐3.2类成员的访问控制☐3.3单继承与多继承☐3.4派生类的构造、析构函数☐3.5类成员的标识与访问3.1 类的继承与派生☐保持已有类的特性而构造新类的过程称为继承。
☐在已有类的基础上新增自己的特性而产生新类的过程称为派生。
☐被继承的已有类称为基类(或父类)。
☐派生出的新类称为派生类。
交通工具汽车小汽车卡车旅行车工具车轿车面包车兼职技术人员销售经理管理人员销售人员雇员继承与派生的目的☐继承的目的:实现代码重用。
☐派生的目的:当新的问题出现,原有程序无法解决(或不能完全解决)时,需要对原有程序进行改造。
派生类的声明class 派生类名: 继承方式基类名{成员声明;};继承方式:public, protected, private(默认)派生类的构成私有成员保护成员公有成员私有成员保护成员公有成员基类部分新定义部分派生类当派生类成员与基类成员同名时遵守同名覆盖原则3.2 类成员的访问控制☐不同继承方式的影响主要体现在:1、派生类成员对基类成员的访问控制。
2、派生类对象对基类成员的访问控制。
☐三种继承方式◆公有继承(public)◆私有继承(private缺省)◆保护继承(protected)私有成员保护成员公有成员基类新定义部分派生类*******保护成员公有成员私有成员保护成员公有成员public注:成员包括数据成员和函数成员基类新定义部分派生类protected私有成员保护成员公有成员*******保护成员保护成员私有成员保护成员公有成员基类新定义部分派生类private私有成员保护成员公有成员*******私有成员私有成员私有成员保护成员公有成员公有继承(public)☐基类的public和protected成员的访问属性在派生类中保持不变,但基类的private成员不可访问。
☐派生类中的成员函数可以直接访问基类中的public 和protected成员,但不能访问基类的private成员。
C++中的继承和派生详解
如图7.1所示,C++中有两种继承:单一继承和多重继承。 对于单一继承,派生类只能有一个基类;对于多重继承, 派生类可以有多个基类。
图7.1 类的单一继承和多重继承的UML结构图
在图7.1中,箭头指向基类。单一继承形成一个倒挂的 树。派生类继承了基类所有的数据成员和成员函数,程 序员也可以在派生类中添加新的数据成员和成员函数。 这样,基类定义了对象的一个集合,派生类通过增添新 的成员限制基类的定义,以便定义基类对象集合的一个 子集。 由此可见,从编码角度讲,派生类从基类中以较低代价 换来了大量的灵活性。一旦产生了可靠的基类,只需要 调试派生类中所做的修改即可。 C++派生类从父类中继承性质时,可使派生类扩展它们, 或者对其做些限制,也可改变或删除,甚至不作任何修 改。所有这些变化可归结为两类基本的面向对象技术。 第一种称为性质约束,即对基类的性质加以限制或删除。 第二种称为性质扩展,即增加派生类的性质。
冒号后“基类名(参数表)”称为成员初始化列表,参数 表给出所调用的基类构造函数所需要的实参。实参的值可 以来自“参数表0”,或由表达式给出。可以像Rectangle 那样,在类中直接定义为内联函数。下面是在类说明之外 定义的示范: Rectangle::Rectangle(int a, int b, int h, int w):Point(a,b) {H=h; W=w; cout<<"Rectangle..."<<endl;} “参数表0”有4个参数,基类Point的参数表是自己的2 个数据成员。 构造函数(包括析构函数)是不被继承的,所以一个派生 类只能调用它的直接基类的构造函数。当定义派生类的一 个对象时,首先调用基类的构造函数,对基类成员进行初 始化,然后执行派生类的构造函数,如果某个基类仍是一 个派生类,则这个过程递归进行。当该对象消失时,析构 函数的执行顺序和执行构造函数时的顺序正好相反。输出 结果也证实了这个结论。
继承和派生(2)
被继承,对滚动条对象成员的使用是通过新类的内
部消息实现的。
多继承的定义
多重继承派生类定义的一般形式:
class 派生类名:继承方式 基类名1, … 继承方式 基类名n { 派生类新增的数据成员和成员函数 };
注意,在每个基类名之前必须有继承方式,如果缺省
继承方式,则表示从该基类私有派生。例如:
class c : public a,b {…}; // c 对 a 公有派生,对 b 私有派生 // c 对 a 私有派生,对 b 公有派生 // c 对 a,b 均为公有派生
class c : a, public b {…};
class c : public a, public b {… };
• 例 多重继承。 #include<iostream> #include<cstring> using namespace std; class Point{ //二维直角坐标点类 protected: float x,y; public: Point(float x,float y) { this->x=x; this->y=y; } void Setxy(float x,float y) { this->x=x; this->y=y; } void Getxy(float &x,float &y) { x=this->x; y=this->y; } void ShowP( ){ cout<<'('<<x<<','<<y<<')'; } };
}
}
class D:public B1,public B2{ protected: int z; public: D(int x,int y,int z):B1(x),B2(y) { this->z=z; cout<<"派生类D的构造函数!\n"; } ~D(){ cout<<"派生类D的析构函数!\n"; } }; int main(void){ D d(1,2,3); return 0; } 程序运行结果: • 说明派生类的对象:先调用各基类的 基类B1的构造函数! 构造函数,后执行派生类的构造函数。 基类B2的构造函数! 若某个基类仍是派生类,则这种调用 派生类D的构造函数! 基类构造函数的过程递归进行。 派生类D的析构函数! • 撤消派生类的对象:析构函数的调用 基类B2的析构函数! 顺序正好与构造函数的顺序相反。 基类B1的析构函数!
十二讲继承与派生共51页文档
3. 基类对象与派生类对象之间的赋 值关系
(1) 基类对象=派生类对象
只是将派生类对象中“共性成员” 赋值给基类对象。
反方向赋值不允许。
(2) 指向基类对象的指针=派生类对 象的地址
通过上述指针可直接访问基类成员 部分,但只有经过指针类型强制转 换才可访问非基类成员部分。
反方向赋值不允许。
12.1 派生类
<基类参数表i>是与<基类名i>所指 基类中某个构造函数的参数表。<对 象成员参数表i>是与<对象成员名i> 所属类中某个构造函数的参数表。
12.1 派生类
12.2 其他特 征的继承关 系
12.3 派生关 系中的二义 性处理
12.4 多态性 与虚函数
系统创建派生类对象的步骤:
(1)调用各基类的构造函数,调用顺 序按照它们被继承时声明的顺序(从 左至右)。
假设类A是类B的派生类
(1) 类A对象的创建必然包含类B对象 的创建。显然,类A对象也包含类B 对象的私有成员。
(2) 类A对象的创建和释放和其基类 对象及成员对象相联系。
12.1 派生类
12.2 其他特 征的继承关 系
12.3 派生关 系中的二义 性处理
12.4 多态性 与虚函数
派生类对象的初始化: 需要对基类的数据成员、派生类
12.4 多态性 与虚函数
1.友元关系以及静态成员的继承
友元关系的继承:
(1) 当基类含有友元成员时,该基类 的派生类不一定含有上述友元成员。
(2)当派生类从基类继承过来的成员 原先是某类的友元,那么派生类的 成员仍然是某类的友元。
12.1 派生类
12.2 其他特 征的继承关 系
9类的继承和派生
9.1 基类与派生类
► 类的对象是各自封闭的,如果没继承性机制,则类对象中数据、函 数就会出现大量重复。
► 继承改变了传统程序设计中对不再使用的数据类型和函数进行改写 甚至重写的方法,克服了程序无法重复使用的缺点。
► 通过继承,可以吸收现有类的数据和函数来创建新类,并增添新的 成员增强此类,这样可以节约程序开发的时间。
► 派生类的成员列表描述的是派生类自己新增加的数据成员和成员函 数。
12
9.2 派生类的定义
【例9.1】派生类举例
1#include <iostream>
2using namespace std;
3class Base //基类
4{
5 private:
6
int b_number;
7 public:
10
int get_number( ) {return b_number;}
11
void print( ) {cout << b_number << endl;}
12 };
2
9.4 派生类的举例
13 class Derived : public Base //派生类
14 {
15 private:
16
► (4)友元关系不能继承。一方面,基类的友元对派生类的成员没 有特殊访问权限。另一方面,如果基类被授予友元关系,则只有基 类具有特殊访问权限,该基类的派生类不能访问授予友元关系的类。
1
9.3 派生类的构成
► (5)如果基类定义了静态成员,则整个继承层次中只有一个这样 的成员。无论从基类派生出多少个派生类,每个静态成员只有一个 实例。
//基类的print //派生类的print
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验继承与派生
一、实验目的
1)掌握继承的实现方法;
2)继承中常见问题的处理方法。
二、实验内容
2.1分析下面的程序,指出程序运行的结果
1.#include<iostream.h>
class CBase
{public:
void fn1();
};
void CBase::fn1()
{cout<<"调用基类类的函数fn1()\n";
}
class CDerived:public CBase
{
public:
void fn1();
};
void CDerived::fn1()
{cout<<"调用派生类的函数fn1()\n";
}
void main()
{
CDerived d1;
CBase *pb=&d1;
CBase &pd=d1;
d1.fn1();
pb->fn1();
pd.fn1();
}
2.2编写并调试程序:
1)定义一个图形类,其中有保护类型的成员数据:高度和宽度,一个公有的构造函数。
由该图形类建立两个派生类:矩形类和等腰三角形类。
在每个派生类中都包含一个函数area(),分别用来计算矩形和等腰三角形的面积。
2)编写一个程序设计一个汽车类vehicle,包含的数据成员有车轮个数wheels 和车重weight。
小车类car是它的私有派生类,其中包含载人数passenger_load。
卡车类truck是vehicle的私有派生类,其中包含载人数passenger_load和载重量payload,每个类都有相关数据的输出方法。