4 派生类与继承
派生类与继承应用举例
#include <iostream.h>
#include <math.h>
const double PI=3.1415926;
class Circle //圆类
{ protected:
double r; //半径
public:
Circle(double radius=0): r(radius) { }
public:
Cylinder(double radius=0,double height=0):Circle(radius)
{ h=height; }
double Area( ) //计算圆柱体的表面积
{ return 2*PI*r*(r+h); }
double Volume( ) //计算圆柱体的体积
}
long get_capacity(void) { return capacity; }
void display_disk(void)
{ cout<<side<<" "<<track<<" "<<sector<<" "; }
};
class hard_disk:public disk
{ private:
{ return PI*r*r*h; }
};
class Cone: public Circle //圆锥体类
{ double h; //高度
public:
Cone(double radius=0,double height=0):Circle(radius)
{ h=height; }
继承与派生
4.1 继承和派生的概念
在软件开发过程中,在定义特殊类时,不需把它的一 般类已经定义过的属性和服务重复地书写一遍,只需要声 明它是某个类的特殊类,并定义它自己的特殊属性和服务。 这将明显地减轻开发工作的强度。 4.1.2 继承的作用 面向对象程序设计的继承性使得大型应用程序的维护 和设计变得更加简单。一方面,大型应用程序设计完成并 交付使用后,经常面临用户的需求发生变化,程序功能需 要扩充等问题。这时程序的修改需要非常谨慎,因为某个 局部的修改可能会影响其他部分,而一个正在使用中的系 统要进行全面的测试,既费时间又有很多实际的困难。另 一方面,一个新的应用系统程序设计在许多方面会和以前 设计过的某个或某些系统的模块非常类似,怎样加快大型 应用程序的开发速度,重用这些已经开发成功的程序模块, 一直是软件设计中迫切需要解决的问题。
4.2 派生类
C++语言派生类多重继承的定义格式如下: class <派生类名>:[继承方式1] [<基类名1>],[继承 方式2] [<基类名2>],…, [继承方式n] [<基类名n>] { <派生类成员变量和成员函数定义> }; 通常,在多重继承时,继承方式设计成一致的形式。 如继承方式均设计成public,或均设计成private。
继承与派生
实验四继承与派生实验名称:继承与派生学时安排:4实验类别:设计性实验实验要求:1人1组一、实验目的和任务1.理解继承的含义;2.学习从现有类派生出新类的方式;3.了解在派生类中如何使用基类的成员。
二、实验设备介绍软件需求: Visual C++ 6.0或VS2008硬件需求: 对于硬件方面的要求,建议配置是Pentium III 450以上的CPU处理器,64MB 以上的内存,200MB的自由硬盘空间、CD-ROM驱动器、能支持24位真彩色的显示卡、彩色显示器、打印机。
三、实验内容和步骤1.新建一个雇员类,它的数据成员有雇员代号,年龄,工资,性别,姓名,输入雇员资料方法,打印雇员资料方法。
2.以此雇员类为基类,从中派生出教师类,其中要求在教师类中加入一个计算教师工资的方法,教师工资=基本工资(1000)+课时(月工作量)×30。
3.以此雇员类为基类,从中派生出实验员类,其中要求在实验员类中加入一个计算实验员工资的方法,实验员工资=基本工资(800)+实验室补助(150)+值班课时(月工作量)×5。
4. 以此雇员类为基类,从中派生出行政人员类,其中要求在行政人员类中加入一个计算行政人员工资的方法,行政人员工资=基本工资(2000)+行政补贴(200)。
5.编写一个完整的程序,要求用户从键盘输入雇员的信息,然后在屏幕显示这些信息。
【任务分解】【程序示例】文件Employee.hclass Employee{protected://补充完成数据成员定义public:……void inputEmployee(); // 用户从键盘输入雇员姓名和受聘日期void showEmployee(); // 显示雇员姓名和受聘日期};文件Teacher.h#include "Employee.h"class Teacher:补充完成代码{private:// 补充完成数据成员定义:如基本工资、课时量。
派生类(继承)的概念
4.1 派生类的概念
上一节 上一页 下一页 下一节
4.1.2 派生类的声明
1.声明派生类的一般格式为: class 派生类名:继承方式 基类名 { //派生类中新增或改写的数据成员和成员 函数 }; 2.继承方式 继承方式可以是public、private和protected,分 别表示公有、私有和保护继承。 系统默认的继承方式为私有(private)继承。
4.1 派生类的概念
class student:public person{ int score; int grade; public: student(……); void print( ) {cout<<name<<“ “<<age <<“ “<<sex<<“ ”<<score <<“ “<<grade<<endl;} }; 从基类person中继承来的私 有数据成员name、age、sex 在派生类中不能直接访问, 如何解决?
类2
下一页 下一节
4.1.2 派生类的声明
引例:构造学生类和雇员类
class student{ char name[10]; int age; char sex; int score; int grade; public: student(……); void print( ) {cout<<name<<“ “ <<age<<“ “<<sex<< “ ”<<score<<“ “<< grade<<endl;} };
protected
C++面向对象技术复习题汇总(含答案)
面向对象程序设计C++复习资料与答案第一、二、六、七章习题一、选择题1、系统约定C++源程序文件名的缺省的扩展名为()A、bccB、c++C、cppD、vcc2、面向对象的程序设计将数据与( )放在一起,作为一个相互依存、不可分割的整体来处理.A、对数据的操作B、信息C、数据隐藏D、数据抽象3、当一个函数无返回值时,函数的类型应定义为()A、voidB、任意C、intD、无4、对于C++的函数,正确的叙述是:A、函数的定义不能嵌套,但函数的调用可以嵌套B、函数的定义不能嵌套,但函数的调用不能嵌套C、函数的定义和调用都不能嵌套D、函数的定义和调用都可以嵌套5、下列语句中错误的是( )A、int *p=new int(10);B、int *p=new int[10]C、int *p=new int;D、int *p=new int[40](0);6、假设已经有定义:const char *const name=”chen”;,下面的语句中正确的是:()A、name[3]=’a’;B、name=”lin”;C、name=new char[5]; D、cout<〈name[3];7、假设已经定义:char *const name=”chen”;, 下面的语句中正确的是:( )A、name[3]=’q';B、name=”lin”;C、name=new char[5];D、name=new char(‘q’);8、假设已经定义:const char *name=”chen”;,下面的语句中错误的是:( )A、name[3]=’q’;B、name=”lin”;C、name=new char[5];D、name=new char(‘q’);9、下面的类型声明中正确的是:( )A、int &a[4];B、int &*p;C、int &&qD、int i,*p=&i;10、假设定义了函数模板( )template 〈class T>T max(T x,T y){ return(x>y)?x:y;}并定义了int i;char c;错误的调用语句是:()A、max(i,i)B、max(c,c)C、max((int)c,i);D、max(i,c)11、模板的使用是为了( )A、提高代码的可重用性B、提高代码的运行效率C、加强类的封装性D、实现多态性12、设有二个语句:int x[‘a’];cin>>x;则编译器认为()A、说明语句int x[‘a’]错B、二个语句都错C、语句cin〉〉x 错D、二个语句正确,没有语法错13、设有语句:void f(int a[10],int &x);int y[10],*py=y,n;则对函数f的正确调用语句是( )A、f(py[10],n);B、f(py,n)C、f(*py,&n)D、f(py,&n)14、在C++中实现封装是借助于()A、枚举B、类C、数组D、函数15、对于下面几个函数:(1) void f(int x,float y){……}(2) int f(int a,float b){…… }(3) int f(int i,int j){……}(4) float k(int x){…… }是重载函数。
第5章 继承和派生类
2010/9/18
第5章 继承和派生类
程序运行结果: x=4 y=5 l=6 w=8 程序分析: 通过公有继承方式,从BaseClas类得到DerivedClass类。 派生类DerivedClass只有一个基类,所以是单继承。基类 BaseClass定义了两个数据成员,3个成员函数。派生类 DerivedClass定义了两个数据成员,3个成员函数。通过 继承,派生类DerivedClass拥有4个数据成员:x、y、l和 w,6个成员函数:setx ( )、sety ( )、setl ()、setw ( )、 displayxy ( )、displaylw( )。
2010/9/18
面象对象程序设计
第5章 继承和派生类
class Father:private Grandfather //中间类:Grandfather的 公有派生类, //Son的基类 { public: void test() { b1=10; //可以访问,因b1改为private b2=20; //可以访问,因b2改为private b3=30; //不可访问, 因b3改为不可访问 } };
2010/9/18
面象对象程序设计
第5章 继承和派生类
5.1.2 继承的种类
在C++语言中,一个派生类既可以从一个基类派生,也可 以从多个基类派生。从一个基类派生的继承被称为单继承。 单继承形成的类层次是一个倒挂的树,如图5.2所示。从 多个基类派生类的继承被称为多继承。多继承形成的类层 次是一个有向无环图(DAG),如图5.3所示。在图5.2中, 输入设备是基类,从它派生出了3个派生类:键盘类、鼠 标类和扫描仪类。在图5.3中,从教师类和干部类派生出 校长类,即校长类有两个基类。
第5章 派生类与继承
void print();
};
print();
};
//定义一个基类 class person{ protected: char name[10]; int age; char sex; public: //…… }; //定义一个派生类 class employee:public person { protected: char department[20]; float salary; public: //…… };
当类的继承方式为私有继承时,基类的public成员和 protected成员被继承后作为派生类的private成员,派生类 的其他成员可以直接访问它们,但是在类外部通过派生类的 对象无法访问。
基类的private成员在私有派生类中是不可直接访问的, 所以无论是派生类成员还是通过派生类的对象,都无法直接 访问从基类继承来的private成员,但是可以通过基类提供 的public成员函数间接访问。 例5.1一个私有继承的例子
由于派生类继承了基类的成员,派生类的构造 函数需要调用基类的构造函数对其中定义于基 类的数据成员进行初始化。 给基类构造函数传递实际参数是通过向派生类 构造函数传递实际参数以及初始化列表来间接 实现传递的。
5.2.1 派生类构造函数和析构函数的执行顺 序 通常情况下,当创建派生类对象时, 首先执行基类的构造函数,随后再执行 派生类的构造函数; 当撤消派生类对象时,则先执行派生 类的析构函数,随后再执行基类的析构 函数。
例5.3 公有继承的访问规则
表5-3 公有继承的访问规则
基类成员 内部访问 对象访问 Private成员 不可访问 不可访问 public成员 可访问 可访问 protected成员 可访问 不可访问
继承与派生类答案
继承与派生类知识要点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分析:一个派生类可以作为另一个派生类的基类。
C++试题
判断题1构造函数、析构函数、友元函数都属于类的成员函数。
2静态数据成员是类的所有对象共享的数据。
3 可以将派生类的对象的值赋给基类对象,也可以将基类对象的值赋给派生类对象。
4 派生类默认的继承方式为public。
5 类模板实例化的过程是类模板->模板类->对象。
6 多继承情况下,派生类的构造函数的执行顺序取决于定义派生类时所指定的各基类的顺序。
7 构造函数可以重载,析构函数也可以重载。
8 如果派生类的成员函数的原型与基类中被定义为虚函数的成员函数原型相同,那么,这个函数自动继承基类中虚函数的特性。
9 设A为类,则A类的复制构造函数原型声明为void A(A&)。
10 在公有继承中,基类中只有公有成员对派生类是可见的。
11 在公有继承中,基类的公有成员和私有成员在派生类中都是可见的。
12 虚基类是用来解决多继承中公共基类在派生类中只产生一个基类子对象的问题。
13 派生类是从基类派生出来,他不能生成新的派生类。
14 当一个对象调用成员函数时,编译程序先将对象的地址赋值给this指针后,再调用成员函数。
15 对象是属性和行为的集合。
16 模板的使用是为了加强类的封装性。
17 函数定义时在函数参数表后加=0表示该函数为纯虚函数。
18 可以以”类名::静态成员函数(实参表)”和“对象.静态成员函数(形参表)”两种形式调用类的静态成员函数。
19 语句Int a(5),*p; *p=a;能够正常执行。
20 设A为类,则A *(*fpA[5])()的正确描述是:fpA是一个数组,数组的5个元素都是A类对象。
21 重载双目运算符为成员函数时,一般将左操作数作为函数的参数。
22 可以将插入运算符“ <<”和提取运算符“ >> ”重载为类的成员函数。
23 C++语言中,即允许单继承,又允许多继承。
24 派生类的继承方式有两种:公有继承和私有继承。
25 在私有继承中,基类中所有成员对派生类的对象都是不可见的。
C++程序设计04737 第5章 类的继承与派生
5.1 类的继承与类的派生
5.1.2 派生类的定义与大小
2.类的大小
1. //[程序5-2]基类与子类占用空间及字节对齐
2. #include <iostream>
3. using namespace std;
4. class BaseClass //基类
5. {
6.
int v1, v2;
7.
派生类中包含了基类的成员变量,且基类
成员变量在前,派生类成员变量在后。基 类占用了12个字节,在此之后要分配派生 类自身的成员变量,一个int型变量和一个 指针变量。在64位系统中,指针占8个字 节。所以派生类的大小=12+4+8=24字节。 32位系统中指针的大小是4字节。
5.1 类的继承与类的派生
5.1 类的继承与类的派生
5.1.3 继承关系的特殊性
//[程序5-3]派生类继承了友元函数
#include <iostream>
using namespace std;
class another;//前向引用声明
class Base//基类
{private: float x;
public: void print(const another &K);};
d.print(ano);//输出: Base: 100
return 0;
}
如果派生类Derived中重写了print(),若还想在函数中访问another的私有成员,则必须将类Derived的print()函数也
声明为another的友元。在类another中需要添加如下声明:
friend void Derived::print(const another &K);//派生类的成员函数声明为本类的友元
第4章 派生类与继承
如:
class employee:public person{ char department[20]; float salary; public: //… };
Previous Next Back
5
派生方式
1. 私有派生
class employee:private person{ //… };
//部门 //工资
直接定义employee类,代码重复非常严重。 使用继承:将employee说明成person类的派生类。 增加新的数据成员department和salary; 修改print成员函数。
Previ:
class 派生类名:派生方式 基类名{ //派生类新增的数据成员和成员函数 };
class B{ public: void setB(int x){ b=x; } void showB(){ } private: int b; };
class C : public A, private B{ public: void setC(int x, int y, int z) { //直接访问基类的公有成员 setA(x); setB(y); c=z;} void showC(){ } private: int c; }; void main() { C obj; obj.setA(5); obj.showA( ); obj.setC(6,7,9); obj.showC( ); obj.setB(6); //错误 obj.showB(); //错误 }
公有派生
class employee:public person{ //… }; public
基类
private a fun1() public c fun2() private
第5章 类的派生与继承
第5章 类的派生与继承
class BaseClass //基类 {
int vl,v2; }; class DerivedClass : public BaseClass //派生类 {
int v3; };
第5章 类的派生与继承
二、派生类的定义与大小 1、派生类的定义 从基类派生派生类的一般格式: class派生类名:继承方式说明符 基类名 {
编程小技巧:同学们可以将鼠标放置于类中的任何一个成 员或者函数上,编程软件会提示,对应的访问权限,这个方法在 继承编程中特别好用。
第5章 类的派生与继承
我们几乎不使用 protected 或 private 继承,通常使用 public 继承。当使用不同类型的继承时,遵循以下几个规则: 公有继承(public):当一个类派生自公有基类时,基类的公
第5章 类的派生与继承
C++程序设计
第5章 类的派生和继承
第5章 类的派生与继承
本章内容
类的继承与类的派生 访问控制 派生类的构造函数和析构函数 类之间的关系 多层次派生 基类与派生类指针的相互转换
第5章 类的派生与继承
第一节 类的继承与类的派生
常考知识点: 继承派生基本概念 继承派生在C++中起到的作用 派生类定义的方法 派生类从基类继承的元素有哪些 继承关系中友元和静态成员变量的派生特点 单继承、多重继承的概念以及异同 派生的层次
第5章 类的派生与继承
1、继承:在一个已存在的类的基础上建立一个新的类,称 为继承
2、派生:从已有的类(父类)产生一个新的子类,称为类的 派生
3、单继承:一个派生类只从一个基类派生,这称为单继承 4、多继承:一个派生类有两个或多个基类的称为多重继承
继承的原理
继承的原理
继承是面向对象编程中的一个重要概念,它是指一个类可以派生出子类,子类将继承父类的属性和方法。
继承的原理是通过类之间的关系连接起来,可以实现代码的重用和扩展。
在继承的关系中,父类被称为基类或超类,子类被称为派生类。
子类可以继承父类的属性和方法,这意味着子类可以直接访问基类中已有的数据和行为。
通过继承,子类可以拥有父类的特性,并且可以进一步添加新的特性或修改父类的特性。
继承的实现方式可以使用关键字“extends”,将子类关联到父类。
子类可以拥有父类中的所有非私有属性和方法,并且可以通过关键字“super”访问父类的构造函数和方法。
在父类中,可以
使用关键字“protected”定义的成员可以被子类访问。
继承的好处在于代码的重用和扩展。
当多个类有相似的属性和方法时,可以将这些相似的部分提取到父类中,子类可以直接继承这些公共的部分。
这样可以减少代码的冗余,并且使得代码更易于维护和扩展。
另外,通过继承,可以实现多态性,子类可以表现出与父类不同的行为,而不改变代码的接口。
需要注意的是,在使用继承时要满足“is-a”关系,即子类应该
是父类的一种特殊情况。
继承应该符合逻辑的结构,避免出现不合理的继承关系。
继承是面向对象编程中的一个重要特性,它可以实现代码的重
用和扩展。
正确使用继承可以提高代码的可维护性和可扩展性,同时也能减少代码的冗余。
第五章 类的继承与派生
//save as car.h #include "vehicle.h" class car : public vehicle { //派生类car(轿车) public: void setcar(int aw, int ats, float ap, int anc, int ahp) {setvehicle(aw,ats,ap); //调用基类的函数初始化 numbercylinders=anc; horsepower=ahp; } void print( ) { //重定义print( ) vehicle::print( ); //调用基类的函数 cout << "\n cylinders:" << numbercylinders; cout << "\n horsepower:" << horsepower;} private: int numbercylinders; //汽缸数 int horsepower; //马力 };
子类特有的部分
子类名
public、protected 和 private分别表示公有继承、保护 继承和私有继承,定义派生类时三选一。
7
第五章 类的继承与派生
(3)说明 ①public继承 最常见的派生方式。基类成员的访问权限在派生类中保 持不变,派生类成员函数不可直接访问基类的private成员, 可通过基类的公有成员函数或保护成员函数访问。 ②private继承 基类中的所有成员在派生类中都将变为private成员。 派生类成员函数不可直接访问基类的private成员,但可直 接访问基类的public、protected成员,并通过它们访问基 类的private成员。 ③protected继承 基类的public成员在派生类中变为protected成员,基类 的protected和private成员在派生类中保持原来的访问权限。 8
C++面向对象程序设计第8章 继承与派生
蚌埠学院计算机系
C++面向对象程序设计
class Studend1 可以看出,很多是重复的地方, 我们可以通过C++语言中的 { int num; //此行原来己有 继承机制,可以扩充和完善旧 char name[20]; //此行原来己有 的程序设计以适应新的需求。 char sex; //此行原来己有 这样不仅可以节省程序开发的 时间和资源,并且为未来程序 int age; 增添了新的资源。 char addr[20]; public: void display( ) ; //此行原来己有 {cout<<"num: "<<num<<endl; //此行原来己有 cout<<"name: "<<name<<endl;//此行原来己有 cout<<"sex: "<<sex<<endl; //此行原来己有 cout<<"age: "<<age<<endl; cout<<"address: "<<addr<<endl;} };
蚌埠学院计算机系
21
C++面向对象程序设计
【例8-3】定义类Point,然后定义类Point的派生类 Circle。 #include <iostream.h> class Point //定义基类,表示点 { private: int x; int y; public: void setPoint(int a, int b){ x=a; y=b; }; //设置坐标 int getX(){ return x; }; //取得X坐标 int getY(){ return y; }; //取得Y坐标 };
派生类对基类的默认继承方式
派生类对基类的默认继承方式在面向对象编程中,派生类对基类的默认继承方式是非常重要的概念。
它决定了派生类在没有指定继承方式的情况下,如何继承基类的成员。
在本文中,我们将深入探讨派生类对基类的默认继承方式,并讨论其在实际编程中的应用与使用。
1. 派生类与基类的关系在面向对象编程中,类可以通过继承的方式来扩展已有类的功能。
其中,原有的类称为基类(或父类),新创建的类称为派生类(或子类)。
派生类可以继承基类的属性和方法,并且可以在此基础上进行扩展和修改。
2. 默认继承方式当我们创建一个派生类时,并没有明确指定继承方式时,C++、Java和Python等编程语言都有默认的继承方式。
默认继承方式决定了派生类如何继承基类的成员,包括公有成员、保护成员和私有成员。
接下来,我们分别来讨论这三种情况。
3. 公有成员的默认继承方式对于公有成员来说,派生类对基类的默认继承方式是公有继承。
这意味着基类中的公有成员在派生类中仍然是公有的,可以被派生类的对象和外部访问。
这种默认继承方式使得派生类可以直接继承基类的接口和实现,从而可以直接使用基类的功能。
4. 保护成员的默认继承方式对于保护成员来说,派生类对基类的默认继承方式是保护继承。
这意味着基类中的保护成员在派生类中仍然是保护的,可以被派生类的成员函数和友元访问,但不能被派生类的对象和外部访问。
这种默认继承方式使得派生类可以在继承基类的基础上进行修改和扩展,同时保护基类的实现细节。
5. 私有成员的默认继承方式对于私有成员来说,派生类对基类的默认继承方式是私有继承。
这意味着基类中的私有成员在派生类中是不可访问的,只能被基类的成员函数和友元访问。
这种默认继承方式使得派生类无法直接访问基类的私有成员,从而有效地隐藏了基类的实现细节。
6. 总结与回顾在本文中,我们探讨了派生类对基类的默认继承方式。
通过对公有成员、保护成员和私有成员的讨论,我们了解了派生类在默认情况下如何继承基类的成员。
《C++程序设计》电子教案第5章 继承和派生
// 使用基类成员i,j
// 使用基类成员i,j
4.私有继承和保护继承
私有继承:派生类对基类的私有继承使用关键 字private描述(可缺省),基类的所有公有段 和保护段成员都成为派生类的私有成员。 保护继承:派生类对基类的保护继承使用关键 字protected描述,基类的所有公有段和保护段 成员都成为派生类的保护成员,保护继承在程 序中很少应用。
常用的三种继承方式:
1.公有继承(public) 公有继承的特点是基类的公有成员和保护成员作为派生类 的成员时,它们都保持原有的状态,而基类的私有成员 仍然是私有的。 2.私有继承(private) 私有继承的特点是基类的公有成员和保护成员作为派生类 的私有成员,并且不能被这个派生类的子类访问。 3.保护继承(protected) 保护继承的特点是基类的所有公有成员和保护成员都成为 派生类的保护成员,并且只能被它的派生类成员函数或 友元访问,基类的私有成员仍然是私有的。
第5章 继承和派生
5.1 5.2 5.3 5.4
基类和派生类 单继承 多继承 虚基类
5.1 基类和派生类
5.1.1 5.1.2 5.1.3 5.1.4
派生类的定义格式 派生类的三种继承方式 访问控制 基类和派生类的关系
返回首页
称已存在的用来派生新类的类为基类,又称为 父类。由已存在的类派生出的新类称为派生类, 又称为子类。派生类可以具有基类的特性,共 享基类的成员函数,使用基类的数据成员,还 可以定义自己的新特性,定义自己的数据成员 和成员函数。
public: void initr(float x,float y,float w,float h) { initp(x,y); //调用基类的公有成员 W=w;H=h; } float getH(){return H;} float getW(){return W;} private: float W,H; }; void main() { rectangle rect; rect.initr(2,3,20,10); rect.move(3,2); cout<<"the data of rect(x,y,w,h):"<<endl; cout<<rect.getx()<<","<<rect.gety()<<","<<rect.getW()<<"," << rect.getH()<<endl; }
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
派生类的构造函数和析构函数
在继承机制中,基类的构造函数和析构函数是不能继承的。 在执行派生类的构造函数时,需要通过成员初始化表,调用 基类构造函数并提供基类构造函数所需的参数。 如果派生类的基类也是派生类,每个派生类只负责其直接基 类的构造,依次上溯。 派生类的构造函数定义一般格式如下:
class student { …… }; class GraduateStudent:public student { …… }; void fn(student &s) { …… } void main() { GraduateStudent gs; fn(gs); //student &s=gs;
继承的概念
在c++中,有二种继承: 1.单继承:从一个基类派生的继承。 2.多继承:从多个基类派生的继承。
继承的概念
继承机制除了支持软件复用外,还具备以下三个作用: 1.对事物进行分类。 2.支持软件的增量开发。 3.对概念进行组合。 派生类使我们可以重用已有类的代码和数据结构,并使程 序 易于维护。但类的友元不可被派生类继承。
第4章 派生类与继承
华东理工大学计算机系· 谢晓玲
继承的概念
继承主要是指在己有类的或称为基类的基础上创建新类的 过程,这个新类就是派生类。 派生类自动的包含了基类的所有的数据和操作,而且它还 可以增加自身新的成员。 继承是面向对象的语言提供的一种重要机制,它在类与类 之间建立了层次关系。 交通工具 汽车 小汽车 工具车 轿车 卡车 面包车 旅行车
派生类的构造函数和析构函数
class Student { //定义学生基类 protected: int number; //学号 char name[20]; //姓名 char Sex; //性别,男性:M,女性:F public: Student() { //重定义的默认构造函数 number=0; strcpy(name,"No name"); Sex='M'; } Student(int n,char *s,char x){ //带参数的构造函数 number=n; strcpy(name,s); Sex= x; } };
任何方式都不能直接访问, 但 可 以 通 过 基 类 的 public、 protected 成 员函数间接访问访问
派生类的继承方式
若派生类的成员函数与基类的成员函数同名,则派生类的成 员函数覆盖继承下来的同名的基类的成员函数。 “基类::成员函数”,则编译器认为是基类的成员函数。 “不可访问”的成员是限制还要严格的成员,即使是类自身 的成员函数也不能访问。 “不可访问”的成员总是由基类继承下来的,它要么是基类 的不可访问成员,要么是基类的私有成员。 公有派生类是基类的一种,其对象可用于基类对象适用的任 何地方。建议使用公有派生。
建议:用protected(保护)代替private(私有)来隐藏数据 成员。
派生类的继承方式
int main() { Base b1(5, 6, 7); //cout<< b1.a; //错误,无法访问对象的私有成员 //cout<<b1.b; //错误,无法访问对象的保护成员 cout<<b1.c<<endl; //正确,可以访问对象的公有成员 cout<<b1.geta()<<endl; //正确,间接访问对象的私有成员a Sub s1(11,15,19,22); s1.test(); //正确,可以访问对象的公有成员 s1.c = 200; //正确,可以访问对象的公有成员 s1.fun3(); //正确,可以访问对象的公有成员 return 0; }
派生类构造函数和析构函数的执行顺序
通过继承,派生类得到了基类的成员,因此派生类 对象中既包括自身类的数据成员还包括通过继承从基 类中得到的数据成员。 在派生类中还可用其他类来定义对象作为成员,又 涉及到派生类中对象成员的构造问题,则当用派生类 定义对象后,派生类对象、对象成员、基类对象的构 造函数的调用顺序如下: 1.基类的构造函数。 2.对象成员的构造函数(如果有的话),有多个时 按声明的顺序。 3.派生类的构造函数。 析构函数的执行顺序与之相反。
//修改私有成员a的值
//返回私有成员a的值
//基类的构造函数
class Sub: public Base { private: int d; public: Sub(int i, int j, int k, int d=m; } void test() { //cout<<a<<endl; cout<<b<< endl; cout<<c<< endl; //fun1(); fun2(); fun3(); seta(10); cout << d <<endl; } };
派生类的构造函数和析构函数
多继承下派生类的构造函数与单继承下派生类构造函数相 似,它必须同时负责该派生类所有基类构造函数的调用。 派生类构造函数执行顺序是先执行所有基类的构造函数, 再执行派生类本身构造函数。 处于同一层次的各基类构造函数的执行顺序取决于声明派 生类时所指定的各基类顺序,与派生类构造函数中所定义的成 员初始化列表的各项顺序无关。 另外,析构函数的调用顺序则与构造函数完全相反。 派生类的构造函数格式如下:
派生类名(总参数列表):基类构造函数(参数列表1),子 对象成员1(参数列表),数据成员(参数),„„ { 派生类构造函数体 }
这里总参数表:须包含所有成员初始化表所须的参数。
派生类的构造函数和析构函数
若基类中定义了缺省构造函数,则在派生类的构造函数的 成员初始化表中,可以省略了基类构造函数名,那么意味调用 的是基类的缺省构造函数。 例如:B( ){ b=0; } 解释为: B( ):A( ){ b=0; } 若基类中定义了有参数的构造函数,或者所定义的缺省构 造函数不能完成基类成员的构造,则必须通过派生类构造函数 的“成员初始化列表”,显式地调用基类的构造函数,向带参 数的构造函数传递参数。 若派生类没有任何构造函数,那么派生类的基类须有缺省 构造函数。 建议为每一个类定义一个缺省的构造函数,即使什么也不 作。
派生类的继承方式
继承方式有3种: 1. public(公有继承) 基类的公用成员和保护成员被派生类继承,并 保持原有的状态。 2. private(私有继承) 基类的公用成员和保护成员被派生类继承,作 为派生类的私有成员。以后不能被这个派生类的 子类所继承。 3. protected(保护继承) 基类的公用成员和保护成员被派生类继承,作 为派生类的保护成员。并且只能被派生类的成员 函数或友元访问。
派生类的构造函数和析构函数
//主函数 int main() { UGStudent st1; UGStudent st2(1001,"Zhang",'F',20,2009,6,11); st1.Print(); st2.Print(); return 0; }
派生类的构造函数和析构函数
单继承的派生类
派生类的构造函数和析构函数
成员初始化表的作用: 1. 初始化派生类中普通数据成员,比如:const成员、引用成 员、普通成员,以及对象成员的构造。 2. 为基类构造函数传递参数。 因此派生类的构造函数定义一般格式如下:
派生类名(总参数列表):基类构造函数(参数列表1), 子对象成员1(参数列表),数据成员(参数),„„ { 派生类构造函数体 }
派生类的成员函数可以直 接访问 在 派 生 类 protected 中 为
protec ted
派生类的成员函数可以直 接访问 在派生类中被隐藏,无法 访问——不可访问
任何方式都不能直接访问, 但 可 以 通 过 基 类 的 public、 protected 成 员函数间接访问
任何方式都不能直接访问, 但 可 以 通 过 基 类 ห้องสมุดไป่ตู้ public、 protected成 员函数间接访问访问
不同的继承方式,导致原有基类成员在派生类中的 访问属性也有所不同。
基类成 员的权 限 public 继承方式 public 在派生类中为public 派生类的成员函数和类的 作用域之外,都可以直接 访问 在 派 生 类 中 为 protected 派生类的成员函数可以直 接访问 privat e 在派生类中被隐藏,无法 访问——不可访问 protected 在 派 生 类 protected 中 为 private 在派生类中为private 派生类的成员函数可以直 接访问 在派生类中为private 派生类的成员函数可以直 接访问 在派生类中被隐藏,无法 访问——不可访问
class UGStudent: public Student { //大学生派生类 public: UGStudent (int n,char *s,char x,int a,int y,int m,int d): Student(n,s,x),birth(y,m,d) { 通过成员初始化表,传递基类的构造 age=a; 函数、成员对象的构造函数。. } UGStudent () { //此处省略了Student()调用 age=0; } void Print() { cout<<"number:"<<number<<endl; cout<<"name:"<<name<<endl; cout<<"sex:"<<Sex<<endl; cout<<"age:"<<age<<endl; cout<<"birthday:"; birth.Print(); } private: int age; Date birth; //对象成员 };