当前位置:文档之家› C++教程继承与派生

C++教程继承与派生

C++教程继承与派生
C++教程继承与派生

第8章继承与派生

8-1. 教学目的与要求

1.理解继承的概念;

2.掌握继承的实现方法;

3.继承中常见问题的处理方法。

8-2. 主要内容及重点:

类是C++中进行数据封装的逻辑单位。继承是面向对象程序设计的一个重要特征之一,它允许在既有类的基础上创建新的类,新类可以从一个或多个既有类中继承操作和数据,而且可以重新定义或加进新的数据和操作,从而形成类的层次或等级。既有类称为基类或父类,在它基础上建立的新类称为派生类、导出类或子类。

本章的重点是派生类的定义和使用、创建派生类对象时构造函数的调用顺序、多重继承中的冲突及其消除方法以及作用域运算符的几种使用方法等。

本章的难点是基类的初始化、多重继承中的冲突以及虚基类等。

8-3. 第8章继承-课件

3-4. 8-4. 第8章继承-复习总结

继承是面向对象程序设计方法的基本特性之一,继承可以提高软件的重要性。

本章主要介绍了C++中的继承性的实现方法以及在继承性常见问题的处理方法。包括基类的初始化、访问类型的调整、冲突及其消除方法、成员覆盖、赋值兼容性以及虚基类等。

类的派生包括三种类型:私有派生、保护派生、公有派生。利用构造函数的初始化成员列表,可以在派生类中对基类成员进行初始化。在继承层次关系中要避免冲突的产生,通常是采用指定作用域和定义虚基类这两种方法来解决问题。

8-5. 第8章继承-练习

8-5-1.思考题:

1).派生类有几种方式,每种方式中派生类对基类成员的继承如何?

2). 在创建派生类对象时,构造函数的执行次序是怎样的?析构函数的执行次序是怎样的?

3). 派生类对象如何对基类中的成员进行初始化?

4). 在多重继承中,在什么情况下会产生冲突?如何消除冲突?

5). 列举我们已学习的作用域运算符“::”的所有用途。

6). 属于不同类的对象在什么情况下可以互相赋值?

7).什么叫虚基类?为什么要引进虚基类?

8-5-2.练习题:

课后练习题见练习单元。

类是C++中进行数据封装的逻辑单位。继承是面向对象程序设计的一个重要特征之一,它允许在既有类的基础上创建新的类,新类可以从一个或多个既有类中继承操作和数据,而且可以重新定义或加进新的数据和操作,从而形成类的层次或等级。既有类称为基类或父类,在它基础上建立的新类称为派生类、导出类或子类。

8.1 继承与派生的基本概念

交通工具

汽车

小汽车卡车游行车

工具车轿车面包车

8.1.1单继承和多继承:

单继承:一个类继承一个一般类特性的继承称为单继承。

多继承:一个类可以继承多个一般类的特性,然后再在继承来的这些一般类的基础上增加自己的特殊性,这种继承方式称为多继承。

如:一个助教博士,他既是一个学生,又是一个老师,如果从学生类和老师类两个一般类继承特性,则助教博士类可以获得这两个类的特性,因而能进一步增强开发效率。

单继承是所有面向对象程序设计语言都具有的功能,但并不是所有的语言都支持多继承,这是由多继承实现的复杂性决定的。C++语言支持多继承。

8.1.2基类和派生类:

在定义类B 时,如果它使用了一个已定义的类A 的部分或全部成员,则称类B 继承了A ,或由类A 派生出类B 。并称类A 为基类或父类,类B 为派生类或子类。

一个派生类又可以作为另一个类的基类,这样一个基类可以直接或间接派生出若干个派生类,构成树状的继承关系。

但是注意:继承关系不可循环。如:A 继承B ,B 继承,C 又继承A ,这是非法的。

例类Y 继承类X 的特性,类Z 又继承类Y 的特性,从而间接继承来类X 的特性。因而类X 是类Y 的直接基类,是类Z 的间接基类,类Y 是类X 的直接派生类,类Z 是类X 的间接派生类。类X 、Y 、Z 形成了一个类层次。

如前图.

8.1.3 两个类之间要具有继承关系,它们通常满足:

1)有共同的属性或操作。

2)有细微的差别。

8. 2 派生类说明及其构造函数和析构函数

8.2.1 派生类的说明

从一个基类派生出子类的一般格式为;

class <派生类名>:<基类名>

{ baseClass derived A derived B

单继承 baseClass A derived C baseClass B 多继承

…//类体,派生类新增的数据成员和成员函数

} ;

其中:

1) class 是类定义的关键字,用于告诉编译器下面定义的是一个类。

2)派生类名是新定义的类名。

3)访问属性是访问说明符,可以是private、public、protected之一。此项的默认值为private,派生类名和访问属性之间用冒号隔开。派生类的访问控制由访问属性来确定,它按下述方式来继承基类的访问属性。

①.公有派生

如果访问属性是为public,则基类的public成员是派生类的public成员;基类的protected 成员是派生类的protected成员;基类的private成员是派生类的private成员;即基类的private 成员对派生类仍保持private属性。

显然,派生类中通过公有派生得到的成员还可以被它的子类继承。

②.私有派生

如果访问属性为private,则基类的public和protected成员都是派生类的private成员;这些私有成员能够被派生类的成员函数直接访问;但在派生类之外不可以被直接访问。但基类的private成员对派生类仍然保持private属性,即不能被派生类成员函数访问。总之当访问属性为private时,派生类的对象不能访问基类中以任何方式定义的成员函数。

显然通过私有派生得到的派生类再派生子类时,其继承得到的基类成员不能被它的子类所继承。

③.保护派生

如果访问属性为protected,则基类的public和protected成员均是派生类的protected成员;基类的private成员对派生类仍保持private属性。具体来说,基类中声明为protected的数据只能被基类的成员函数或其派生类的成员函数访问;不能被派生类以外的成员函数访问。

对保护派生,基类中的公有成员和保护成员在派生类中均变为保护成员,它们仍然可被它的子类所继承。

4)值得注意的是,C++规定派生类只能访问基类中的公有成员和保护成员,而不能访问类中的私有成员。即

无论哪种派生方式,基类中的私有成员既不允许外部函数访问,也不允许派生类中的成员函数访问,但是可以通过基类提供的公有成员函数访问。

5)公有派生与私有派生的不同点在于基类中的公有成员在派生类中的访问属性。

●公有派生时,基类中的所有公有成员在派生类中也都是公有的。

●私有派生时,基类中的所有公有成员只能成为派生类中的私有成员。

6)基类名可以有一个,也可以有多个。如果只有一个基类,则这中继承方式叫做简单继承,也叫单继承;如果基类名有多个,则这种继承方式称为多重继承。各个基类名之间用逗号隔开。

7) 在派生类中声明的名字支配基类中声明的同名的名字,即如果在派生类的成员函数中直接使用该名字的话,则表示使用派生类中声明的名字。

8)在C++中下列成员不能继承:

构造函数和析构函数、友元关系、重载的new和delete运算符。

8.2.2 多重继承

由多个基类派生出一个子类的一般格式为:

class <类名>:<类名1>,<类名2> - - - <类名n> {

--- //类体,派生类新增的数据成员和成员函数

} ;

冒号后面的部分称基类表,各基类之间用逗号分隔,派生方式规定了派生类从基类中按什么方式继承,缺省的派生方式是private。

任一基类在派生类中只能被继承一次。

例:

class z :public x ,y { //类z公有继承了类x ,私有继承了类y

//...

} ;

class z ::x ,public y { //类z私有继承了类x ,公有继承了类y

//...

};

class z::public x ,public y { //类z公有继承了类x和类y

//...

};

8.2.3 派生类的构造函数和析构函数

即基类的初始化

由于派生类继承了基类的一些成员,在创建派生类对象时,对派生类中的数据成员和基类中的数据成员都必须进行初始化,从基类中继承的数据成员可以直接使用基类的构造函数来完成初始化,而新增加的数据成员的初始化要由自己的构造函数来完成。在撤消派生类对象时,也要通过基类的析构函数对派生类中继承得到的数据处理。

1.C++规定,在创建派生类对象时,首先调用基类构造函数,然后再调用派生类构造函数。当撤消派生类对象时,析构函数的调用次序与构造函数的调用次序相反。

2.初始化基类成员通常通过派生类的构造函数实现,一般格式为:

<派生类名>::<派生类构造函数名>():<基类名1>(),--- ,<基类名n>(

{

- - - 派生类的构造函数

}

其中:

1)是派生类构造函数的形参表,它可以由任意类型的变量组成。

2)冒号后列举的部分为初始化成员列表,在初始化成员列表中,一个基类名只能出现一次。

3)当初始化成员列表中某一个基类的构造函数的实参表为空时,可以将该构造函数从初始化列表中删除。

4)、- - - 、分别为调用相应基类构造函数的实参表,其必须与相应构造函数的形参表一致。实参表中的参数可以为任意合法的表达式,该表达式中可以包含中的参数。

5)如果基类中没有默认参数值的构造函数,则必须在派生类的构造函数中通过上述方式向相应的基类的构造函数传递参数。

6)构造函数的调用顺序只与派生类继承的基类的顺序有关,而与初始化成员列表中构造函数顺序无关,与派生类中参数的顺序也无关。

7) 如果基类A的派生类为B,B又派生了C,则在对B进行初始化之前,必须对它的基类A进行初始化,通常是通过B的构造函数实现。但是不能通过C的构造函数实现。即一个类的构造函数只能对它的直接基类的构造函数传递实参。对于更多层继承关系,都可按这种方式递归进行。

8 )如果派生类中包含对象成员,则创建派生类对象时,C++规定构造函数的调用次序为:

基类的构造函数、对象成员的构造函数、派生类的构造函数。

如果,此时基类中有对象成员,调用基类的构造函数之前还要先调用基类对象成员的构造函数,调用次序与前述类同。

在初始化成员列表中,对象成员采用的是对象名,而对基类的初始化使用的是基类的类名,即基类的构造函数名。

调用顺序如下图所示:

基类的基类的构造函数

基类对象成员的构造函

基类的构造函数

派生类对象的构造函数

派生类的构造函数

8.2.4 总结

派生方式(基类的被继承方式) 在基类中的存取权限在派生类中的存取权限

==================================================

public public public

public potected protected

public private (inaccessible)

potected public potected

potected potected protected

potected private (inaccessible)

private public private

private potected private

private private (inaccessible)

==================================================

派生类中可出现四种成员:

1) 不可访问的成员-- 基类的private私有成员被继承过来后,这些成员在派生类中是不可访问的。

2) 私有成员-- 包括在派生类中新增加的private私有成员以及从基类私有继承过来的某些成员。这些成员在派生类中是可以访问的。

3) 保护成员-- 包括在派生类中新增加的potected保护成员以及从基类继承过来的某些成员。这些成员在派生类中是可以访问的。

4) 公有成员-- 包括在派生类中新增加的public公有成员以及从基类公有继承过来的基类的public成员。这些成员不仅在派生类中可以访问,而且在建立派生类对象的模块中,也可以通过对象来访问它们。

8.2.5 例题

(8.2.1 派生类的说明)例题

1.公有派生

如果访问属性是为public,则基类的public成员是派生类的public成员;基类的protected 成员是派生类的protected成员;基类的private成员是派生类的private成员;即基类的private 成员对派生类仍保持private属性。

显然,派生类中通过公有派生得到的成员还可以被它的子类继承。

例1:公有派生中各成员的访问权限

# include

class CBase

{ int x ;

protected ;

int y ;

public:

int z ;

CBase (int a , int b , int c) {x=a ;y=b; z=c;}

int Getx (void ) {return x ;}

int Gety (void ) {return y ;}

void ShowBase (void)

{ cout<<”x=”<

};

class CDerived :public CBase

{ int Length ,Width ;

public :

CDerived ( int a , int b ,int c ,int d , int e) :CBase(a,b,c) //A 表示派生类的构造函数调用//基类的构造函数,从而对继承得到的基类的成员进行初始化。见11.2节。{ Lengh=d ;Width=e ;}

void Show (void )

{ cout<<”Length=”<

cout<<”x=”<

int Sum (void)

{ return Gex ( )+y+z+Length+Width ;}

};

void main ( void )

{ CDerived d1 (1 ,2,3,4,5) ;

d1.ShowBase( ) ;//E,公有成员函数,可以被继承为公有。

d1.show ( ) ;

cout<<”sum=”<

cout<<”y=”<

cout<<”z=”<

}

执行结果:

x=1 y=2 z=3

Length=4 Width=5

x=1 y=2 z=3

Sum=15

y=2

z=3

2.私有派生

如果访问属性为private,则基类的public和protected成员都是派生类的private成员;这些私有成员能够被派生类的成员函数直接访问;但在派生类之外不可以被直接访问。但基类的private成员对派生类仍然保持private属性,即不能被派生类成员函数访问。总之当访问属性为private时,派生类的对象不能访问基类中以任何方式定义的成员函数。

显然通过私有派生得到的派生类再派生子类时,其继承得到的基类成员不能被它的子类所继承。

例2: 私有派生示例

# include

class CBase

{ protected :

int a ;

public :

int b ;

void Set (int x ,int y)

{a=x ;b=y ;}

void Show ( void )

{cout<

};

class CDerived :private CBase

{

public:

void SetD(int x , int y)

{Set (x , y) ;}

void ShowD(void)

{cout<

} ;

void main ( )

{ CBase b1 ;

CDerived d1 ;

b1.Set (1 ,2) ;

b1.Show( ) ;

d1.SetD(10 ,100 ) ;//若d1.set(10 , 100) 则错误,因为set()被私有继承,不能被访问

d1.ShowD( ) ;// d1.Show ( ) 则错误,同上

}

执行结果:

1 2

10 100

假如,还有一个类CCD由派生类CDerived派生出来,定义如下:

class CDD :public Cderived

{

--- //类体

}

则CDD的类体中的成员不能访问CDerived从基类CBase私有继承来的成员,因为这些成员是类CDerived的私有成员,他们不能被类CDD所继承。当然对类CDerived中的保护成员和公有成员在类CDD中仍然可以被访问。

3.保护派生

如果访问属性为protected,则基类的public和protected成员均是派生类的protected成员;基类的private成员对派生类仍保持private属性。具体来说,基类中声明为protected的数据只能被基类的成员函数或其派生类的成员函数访问;不能被派生类以外的成员函数访问。

对保护派生,基类中的公有成员和保护成员在派生类中均变为保护成员,它们仍然可被它的子类所继承。

例3# include

class base

{ protected :

int a ,b ;

public:

void setab (int n ,int m)

{a=n ;b=m;}

};

class derive :public base

{

int c ;

public:

void setc (int n)

{c= n;}

void showabc()

{cout<

};

main()

{

derive obj ;

obj.setab(2,4);

obj.setc(3);

obj.showabc();

return 0 ;

}

执行结果:

2 4 3

Press any key to continue

例4 私有继承方式的保护成员

# include

class base

{ protected:

int a ;

public:

void seta(int sa)

{a=sa ;}

};

class derive 1:private base

{ protected :

int b ;

public:

void setb(int sb)

{b=sb ;}

};

classs derive2:public derive1

{ int c ;

public:

void setc(int sc)

{c=sc;}

void show()

{

cout<<"a="<

cout<<"b="<

cout<<"c="<

}

};

void main()

{ base op1 ;

op1.seta(1) ;

derive1 op2 ;

op2.setb(2 ) ;

derive2 op3 ;

op3.setc(3 ) ;

op3.show ( )

}

(8.2.3 多重继承及派生类的构造函数和析构函数) 例题

例5 派生类中的构造函数和析构函数的调用顺序

# include

class CBase1

{ int x ;

public:

CBase1(int a)

{x=a ;cout<<”调用了基类1的构造函数!\n”;}

~CBase1 ( void )

{ cout<<”调用了基类1的析构函数!\n”;}

};

class CBase2

{ int y ;

public :

CBase2 (int a)

{y=a :cout<<”调用了基类2的构造函数!\n”;}

~CBase2 ( void )

{ cout<<”调用了基类2的析构函数!\n”;}

};

class CDerived :public CBase1 , public CBase2 //A 此处基类顺序影响构造函数的调用顺序。{ int z ;

public:

CDerived ( int a , int b ,int c):CBase1(a) ,CBase2(b) //B初始化基类成员

{ z=c ;cout<<”调用了派生类的构造函数!\n”;}

~ CDerived(void)

{ cout<<”调用了派生类的析造函数!\n”;}

};

void main ( void )

{CDerived d (2, 4 , 6) ;}

执行结果:

调用了基类1的构造函数!

调用了基类2的构造函数!

调用了派生类的构造函数!

调用了派生类的析造函数!

调用了基类2的析构函数!

调用了基类1的析构函数!

7)如果派生类中包含对象成员,则创建派生类对象时,C++规定构造函数的调用次序为:基类的构造函数、对象成员的构造函数、派生类的构造函数。

如果,此时基类中有对象成员,调用基类的构造函数之前还要先调用基类对象成员的构造函数,调用次序与前述类同。

在初始化成员列表中,对象成员采用的是对象名,而对基类的初始化使用的是基类的类名,即基类的构造函数名。

调用顺序如下图所示:

基类的基类的构造函数

基类对象成员的构造函

基类的构造函数

派生类对象的构造函数

派生类的构造函数

例6 派生类中包含对象成员,将前例中的派生类的定义作如下的修改:

# include

class CBase1

{ int x ;

public:

CBase1(int a)

{x=a ;cout<<”调用了基类1的构造函数!\n”;}

~CBase1 ( void )

{ cout<<”调用了基类1的析构函数!\n”;}

};

class CBase2

{ int y ;

public :

CBase2 (int a)

{y=a :cout<<”调用了基类2的构造函数!\n”;}

~CBase2 ( void )

{ cout<<”调用了基类2的析构函数!\n”;}

};

class CDerived :public CBase1 , public CBase2

{ int z ;

CBase 1 b1 ,b2 ;

public:

CDerived ( int a , int b , int c ) :CBase1(a) ,CBase2(b) ,b1(20) ,b2(a*b)

{ z=c ;cout<<”调用了派生类的构造函数!\ n “;}

~CDerived (void )

{ cout<<”调用了派生类的析构函数!\ n “;}

};

void main ( void )

{CDerived d (2, 4 , 6) ;}

如果其它内容不变,则程序输出:

调用了基类1的构造函数!

调用了基类2的构造函数!

调用了基类1的构造函数!

调用了基类1的构造函数!

调用了派生类的构造函数!

调用了派生类的析造函数!

调用了基类1的析构函数!

调用了基类1的析构函数!

调用了基类2的析构函数!

调用了基类1的析构函数!

8) 如果基类A的派生类为B,B又派生了C,则在对B进行初始化之前,必须对它的基类A进行初始化,通常是通过B的构造函数实现。但是不能通过C的构造函数实现。即一个类的构造函数只能对它的直接基类的构造函数传递实参。对于更多层继承关系,都可按这种方式递归进行。

例7多层继承的基类成员的初始化

# include

class A

{protected:

int x ;

public:

A(int a)

{ x=a ;cout<<”调用了类A的构造函数\n”;}

};

class B :public A

{ protected :

int y ;

public:

B ( int a ,int b) :A(a)

{ y=b ;cout<<”调用了类B的构造函数\n”;}

};

class c :public B

{ protected:

int z ;

public:

C ( int a ,int b, int c) :B(a,b)

{ z=c ;cout<<”调用了类C的构造函数\n”;}

};

void main ( )

{A a(1) ;

B b (10 ,20) ;

C c(100 ,200,300) ;

}

执行结果:

调用了类A的构造函数

调用了类A的构造函数

调用了类B的构造函数

调用了类A的构造函数”

调用了类B的构造函数

调用了类C的构造函数

例8:求圆柱的体积

#define PI 3.1415926

# include

class CCircle

{ float r ;

public :

CCircle ( float R) { r = R ;}

float Getr ( void ) {return r ;}

};

class Crectangle

{ float l , w ;//矩形的长和宽

public :

Crectangle ( float L)

{l=L ;}

float Getl ( void )

{return l ;}

};

class CColumn :public CCircle , public Crectangle

{ double v ;//圆柱体的体积public:

CColumn (float L ,float w) :CCircle(W/2),Crectangle(L) { }

void Volumn(void)

{v=PI*Getr()*Getr()*Get1() ;

}

void ShowV olumn(void )

{cout<<”Volumn=”<

};

void main (void)

{CColumn col (7.5,4) ;

col.V olumn( ) ;

col.ShowVolumn();

执行结果:

V olumn=94.2478

例9 (program 8-3 p260)

CA CB

CC

CD

类之间的继承关系

#include

class CA{

int a ;

public:

CA(int n){a=n; cout<<"CA::a="<

~CA(){cout<<"CAobj is destructing"<

};

class CB{

int b;

public:

CB(int n){ b=n; cout<<"CB::b="<

~CB(){cout<<"CBobj is destructing"<

};

class CC: public CA

{ int c;

public:

CC(int n1,int n2):CA(n2) { c=n1; cout<<"CC::c="<

};

class CD:public CB,public CC{

int d;

public:

CD(int n1,int n2,int n3,int n4):CC(n3,n4),CB(n2)

{ d=n1; cout<<"CD::d="<

~CD(){cout<<"CDobj is destructing"<

};

void main(void)

{ CD CDobj(2,4,6,8); }

运行结果为:

CB::b=4

CA::a=8

CC::c=6

CD::d=2

CDobj is destructing

CCobj is destructing

CAobj is destructing

CBobj is destructing

思考:将派生类CD改写为如下形式后,请给出输出结果。

class CD:public CB,public CC {

int d;

CC obcc;

CB obcb;

public:

CD(int n1,int n2,int n3,int n4) :CC(n3,n4), CB(n2), obcb(100+n2), obcc(100+n3,100+n4)

{ d=n1; cout<<"CD::d="<

~CD(){cout<<"CDobj is destructing"<

};

/*

运行结果为:

CB::b=4

CA::a=8

CC::c=6

CA::a=108

CC::c=106

CB::b=104

CD::d=2

CDobj is destructing

CBobj is destructing

CCobj is destructing

CAobj is destructing

CCobj is destructing

CAobj is destructing

CBobj is destructing

Press any key to continue

*/CCobj is destructing

CBobj is destrcting

例10(program 8-1 p252)

假设公司雇员分为:雇员(employee)、经理(manager)、工程师(engineer)、高级主管(director)。

而且假定只关心这几类雇员各自的如下一些数据:

employee(雇员)类:姓名、年龄、工资;

manager(经理)类:姓名、年龄、工资、行政级别;

engineer(工程师)类:姓名、年龄、工资、专业、学位;

director(高级主管)类:姓名、年龄、工资、行政级别、职务。

employee

manager engineer

director

4个类之间的继承关系

#include

#include

class employee //employee类(类型),将作为其它几个类的基类

{ short age;

float salary;

protected:

char * name;

public:

employee (short ag, float sa, char * na)

{ age=ag;

salary=sa;

name=new char[strlen(na)+1];

strcpy(name,na);

}

void print () const

{ cout<<" "<

cout<

cout<

}

~employee() {delete[]name;}

};

class manager:public employee //派生类manager

{ int level;

public:

manager(short ag, float sa, char* na, int lev) :employee (ag,sa,na) //对基类初始化负责

{ level=lev; }

void print()const

{ employee::print(); //调用基类print显示“共性”数据

cout <<" level:"<

}

};

/*注意:允许派生类中的print与基类的print重名,按如下规定进行处理:对子类而言,不加类名限定时默认为是处理子类成员,而要访问父类重名成员时,则要通过类名限定*/

class engineer:public employee //派生类engineer

{ char speciality,adegree;

/*专业:‘E’--电子,‘M’—机械,‘C’—计算机,‘A’—自动化专业;

学位:‘O’—博士,‘M’—硕士,‘B’—学士,‘N’—无学位* / public:

engineer (short ag , float sa , char * na ,char sp ,char ad): employee (ag,sa,na)

{speciality=sp; //派生类的构造函数

adegree =ad;

}

void print()const

{ employee::print(); //调用基类print显示“共性”数据

cout <<" speciality:"<< speciality<

cout <<" academic degree:"<< adegree <

}

};

enum ptitle {PS,GM,VPS,VGM};

class director:public manager //派生类director

{ ptitle post;

public:

director(short ag ,float sa ,char*na , int lev ,ptitle po): manager(ag,sa,na,lev)

{ post =po ; } //派生类的构造函数

void print()const

{ manager::print();

cout <<" post:"<< post <

}

};

void main() { //主函数

employee emp1(23,610.5,"zhang"), emp2(27,824.75,"zhao");

manager man1(32,812.45,"li",11), man2(34,1200.5,"cui",7);

engineer eng(26,1420.10,"meng",'E','M');

director dir(38,1800.2,"zhou",2,GM);

emp1.print();

emp2.print();

man1.print();

man2.employee::print(); //调用基类的print

eng.print();

dir.print();

}

程序执行后的显示结果如下:

zhang: 23 : 610.5

zhao: 27 : 824.75

li: 32 : 812.45

level:11

cui: 34 : 1200.5

meng: 26 : 1420.1

speciality:E

academic degree:M

zhou: 38 : 1800.2

level:2

post:1

例11(program 8-2 p257)

分析下述程序中的继承与派生关系.

#include

classB{

int priDat;

protected:

int proDat;

public:

int publDat;

};

class D11 : public B {

public:

void f11() {

pubDat=11; //OK! 仍为public

proDat=12; //OK! protected

priDat=13; /ERROR! 基类的私有成员不可访问}

};

class D21 : public D11 {

public:

void f21() {

pubDat=121; //OK! 仍为public

proDat=122; //OK! 仍为protected

priDat=131; //ERROR! 基类的私有成员不可访问}

};

class D12 : protected B {

public:

void f12() {

pubDat=21; //OK! 变为protected

proDat=22; //OK! 仍为protected

priDat=23; //ERROR! 基类的私有成员不可访问}

};

class D22 : public D12 {

public:

void f22() {

pubDat=221; //OK! 仍为protected

proDat=222; //OK! 仍为protected

priDat=223; //ERROR! 基类的私有成员不可访问}

};

class D13: private B {

public:

void f13() {

pubDat=31; //OK! 变为private 可以访问

proDat=32; //OK! 变为private 可以访问

priDat=33; //ERROR! 基类的私有成员不可访问}

};

class D23 : public D13 {

public:

void F23() {

pubDat=311; //ERROR!基类的私有成员不可访问

proDat=321; //ERROR!基类的私有成员不可访问

priDat=331; //ERROR!基类的私有成员不可访问}

};

void main() {

B ob0;

ob0.pubDat=1; //OK! 可以访问public成员

ob0.proDat=2; //ERROR! 不可以访问protected成员

继承和派生实验报告

实验目的与要求: 1.掌握类的继承与派生关系以及实验方法,理解类的层次结构。 2.掌握派生类构造函数初始化基类成员和对象成员的方法。 3.掌握内联函数和默认函数。 4.掌握赋值兼容原则,掌握派生类的复制构造函数和赋值运算符的定义。 实验过程及内容: 1.实践教程实验二十二P81范例:定义一个继承与派生关系的类体系,在 派生类中访问基类成员。 ①先定义一个点类,包含x,y坐标数据成员,显示函数和计算面积的函数成员; ②以点为基类派生一个圆类,增加表示半径的数据成员,重载显示和计算面积的函数; ③定义一个线段类,以两个点类对象作数据成员,定义显示、求面积及长度函数,线段类采用聚合方式,因为有两个端点,不能用派生。 编程测试所定义的类体系。 本实验教程中有源码,请自行运行,体会和熟悉继承与派生的基本概念及实现方法,掌握派生类构造函数初始化基类成员和对象成员的方法等。2. 实践教程P83编程:多层派生练习,由上题Point类和Circle类继续派生出Cylinder类。要求计算圆柱的底面积、侧面积、全面积和体积。 请编写所有完整的成员函数,并编写主函数进行验证。 数据处理 1. (1)

(2)j结果报错,原因是派生类中的成员函数不能访问基类中的私有成员。(3)在Line类中添加两个数据成员。

2. #include #include using namespace std; #define PI 3.14159 class Point{ friend class Line; protected: double x, y ; public: Point(){x = 0 ; y = 0 ; } Point(double xv,double yv){ x = xv; y = yv; } double Area(){return 0;} void Show() { cout<<"x="<

int main(void) // 主函数main(void) { C obj; // 定义对象 system("PAUSE"); // 调用库函数system( ),输出系统提示信息return 0; // 返回值0, 返回操作系统 } 2.先阅读下列程序,写出执行结果。然后输入程序,调试程序,比较结果的正确性。// 文件名: main.cpp #include // 预处理命令 using namespace std; // 使用标准命名空间std class A { protected: // 数据成员: int a; // 数据成员 public: // 公有函数: A(int x): a(x){ } // 构造函数 void Show() const{ cout << a << endl; } // 显示a之值 }; class B { protected: // 数据成员: int b; // 数据成员 public: // 公有函数: B(int x): b(x){ } // 构造函数 void Show() const{ cout << b << endl; } // 显示a与b之值 }; class C: public A, public B { public: // 公有函数: C(int x, int y): A(x), B(y){ } // 构造函数 void Show() const // 显示b之值 { cout << a << "," << b << endl; } }; int main(void) // 主函数main(void) { C obj(5, 18); // 定义对象 obj.Show(); // 显示相关信息 obj.A::Show(); // 显示相关信息 obj.B::Show(); // 显示相关信息 system("PAUSE"); // 调用库函数system( ),输出系统提示信息return 0; // 返回值0, 返回操作系统 }

实验四 继承与派生讲解学习

实验四继承与派生

实验四派生类与继承 【实验类型】验证性实验【实验课时】2学时 【实验目的】 (1)理解类的继承的概念,能够定义和使用类的继承关系。 (2)掌握派生类的声明与定义方法。 (3)熟悉公有派生和私有派生的访问特性。 (4)学习虚基类在解决二义性问题中的作用。 【实验环境】 硬件:计算机 软件:Microsoft Visual C++ 6.0 【实验内容】 1、按要求阅读、编写、调试和运行以下程序。 (1)实验内容 ①定义一个基类MyArray,基类中可以存放一组整数。 class MyArray {public: MyArray(int leng); ~MyArray(); void Input(); void Display(); protected: long int *alist; // 指向动态申请的一组空间 int length;}; // 整数的个数 基类中有构造函数、析构函数、输入数据和输出数据的函数。 ②定义一个类SortArray继承自MyArray ,在该类中定义函数实现排序功能。

③定义一个类ReArray继承自MyArray ,在该类中定义函数实现逆转功能。 ④定义一个类AverArray继承自MyArray ,在该类中定义函数Aver求解整数的平均值。 ⑤定义NewArray类,同时继承了SortArray, ReArray和AverArray,使得NewArray类的对象同时具有排序、逆转、和求平均值的功能。在继承的过程中声明为虚基类,体会虚基类在解决二义性问题中的作用。 (2)实验程序 (参考) 程序如下: #include "iostream.h" #include "process.h" class MyArray {public: MyArray(int leng); ~MyArray(); void Input(); void Display(); protected: long int *alist; // 指向动态申请的一组空间 int length; // 整数的个数 }; MyArray::MyArray(int leng) { length=leng; alist=new long int[length]; if(alist==NULL) { cout<<"对不起,创建失败。请重试。 ";exit(1); } } MyArray::~MyArray() {

实验二 类的继承与派生

实验二类的继承与派生 班级:网络工程1班 姓名:倪冬生 学号:20112346017

一、实验目的 1. 掌握类的声明和使用。 2. 掌握类的声明和对象的声明。 3. 复习具有不同访问属性的成员的访问方式。 4. 观察构造函数和析构函数的执行过程。 5. 学习声明和使用类的继承关系,声明派生类; 6. 熟悉不同继承方式下对基类成员的访问控制; 二.实验内容 1. 设计一个用于人事管理的People(人员)类。考虑到通用性,这里只抽象出所有类型人员都具有的属性:number(编号)、sex(性别)、birthday(出生日期)、 id(身份证号)等等。具有的属性如下:姓名char name[11]、编号char number[7]、性别char sex[3]、生日birthday、身份证号charid[16]。其中“出生日期”声明为一个“日期”类内嵌子对象。用成员函数实现对人员信息的录入和显示。要求包括:构造函数和析构函数、拷贝构造函数、内联成员函数、组合。在测试程序中声明people 类的对象数组,录入数据并显示。 2. 从people(人员)类派生出student(学生)类,添加属性:班号char classNO[7];从people 类派生出teacher(教师)类,添加属性:职务char pship[11]、部门char departt[21]。从student 类中派生出graduate(研究生)类,添加属性:专业char subject[21]、导师teacher adviser;从graduate 类和teacher 类派生出TA(助教博士生)类,重载相应的成员函数,测试这些类。 三 . 实验步骤 1.程序代码 #include #include using namespace std; class Date //日期类 { private: int year; int month; int day; public: Date(){} //默认构造 Date(int y,int m,int d) //带参构造 { year=y; month=m; day=d; }

c++实验3 派生类与继承1

实验三派生类与继承 一、实验目的 1、学习类的继承,能够定义和使用类的继承关系。 2、学习派生类的声明与定义方法。 3、掌握类的定义和对象的声明。 4、熟悉公有派生和私有派生的访问特性。 5、掌握派生类构造函数和析构函数的执行顺序。 6、掌握利用访问声明调整基类成员在派生类中的访问属性。 二、试验内容 1、下面的程序可以输出ASCII字符与所对应的数字的对照表。修改下列程序,使其可以输出字母a到z(或任意两个字符间)与所对应的数字的对照表。class table { public: table(int p) { i=p; } void ascii(void); protected: int i; }; void table::ascii(void) { int k=1; for (;i<127;i++) { cout<

c=m; } void print(void); protected: char *c; }; void der_table::print(void) { cout< using namespace std; #include class table { public: table(int p) { i=p; } void ascii(void); protected: int i; }; void table::ascii(void) { int k=1; for (;i<=122;i++)

继承与派生(二)实验报告

学号:姓名:班级: 实验四继承与派生(二) 【实验目的】 1、理解多重继承的概念; 2、理解为了避免同同一基类出现多个重复的副本而采用的虚基类概念和虚拟继承; 3、学习利用虚基类解决二义性问题。 【实验内容】 题目: 2、设计一个用于人事管理的“people(人员)”基类。考虑到通用 性,仅只抽象出所有类型人员都有的属性:编号、姓名、性别、出生日期、身份证号等;从people(人员)类派生出student(学生)类,并添加属性:班号classNO;从people类派生出teacher(教师)类,并添加属性:职务principalship、部门Department;从student类派生出graduate (研究生)类,并添加属性:专业subject、导师teacher adviser(teacher 类);从graduate类和teacher类派生出TA(助教生)类。设计时注意虚基类的使用,注意重载相应的成员函数。测试这些类。

UML图: Date -year: int -month: int -day: int <>-Date(y: int, m: int, d: int) <>-Date(D: Date) +init(y: int, m: int, d: int): void +show(): void people #m_date: Date #m_no: long #m_ident_no: string #m_name: string #m_sex: string <>-people(no: long, name: string, sex: string, ident_no: string, year: int, month: int, day: int) <>-people(no: long, name: string, sex: string, ident_no: string, date: Date) <>-people(p: people) +init(no: long, name: string, sex: string, ident_no: string, year: int, month: int, day: int): void +init(no: long, name: string, sex: string, ident_no: string, date: Date): void +init(p: people): void +show(): void student #m_classno: string <>-student(person: people, classno: string) <>-student(stu: student) +show(): void teacher #m_principalship: string #m_department: string <>-teacher(p: people, principalship: string, department: string) <>-teacher(stu: teacher) +show(): void graduate #m_subject: string #m_adviser: teacher <>-graduate(s: student, subject: string, t: teacher) <>-graduate(g: graduate) +show(): void TA <>-TA(g: graduate, t: teacher) <>-TA(t: TA) +show(): void

实验六继承与派生

继承与组合 一、实验目的 1.了解继承在面向对象程序设计中的重要作用。 2.进一步理解继承与派生的概念。 3.掌握通过继承派生出一个新的类的方法。 4.了解虚基类的作用和用法。 5.掌握类的组合 二、实验内容 1.请先阅读下面的程序,写出程序运行的结果,然后再上机运行程序,验证自己分析的结果是否正确。 (1) #include using namespace std; class A {public: A(){cout<<"A::A() called.\n";} virtual ~A(){cout<<"A::~A() called.\n";} }; class B:public A {public: B(int i) { cout<<"B::B() called.\n";

buf=new char[i]; } virtual ~B() { delete []buf; cout<<"B::~B() called.\n"; } private: char *buf; }; void fun(A *a) { cout<<"May you succeed!"<

A::A() called. B::B() called. May you succeed! B::~B() called. A::~A() called. (2) #include using namespace std; class A{ public: A(int a,int b):x(a),y(b){ cout<<"A constructor..."<

第三次上机实验:继承与派生类上机实践指导

继承与派生类上机实践指导 一.实验目的 1.理解继承的含义,掌握派生类的定义方法和实现; 2.理解公有继承下基类成员对派生类成员和派生类对象的可见性,能正确地访问继承层次中的各种类成员; 3.理解保护成员在继承中的作用,能够在适当的时候选择使用保护成员以便派生类成员可以访问基类的部分非公开的成员; 二.实验内容 1. (1) 将例5.3的程序修改、补充,写成一个完整、正确的程序,用保护继承方式。在程序中应包括输入数据的函数。(2) 修改例5.3的程序,改为用公用继承方式。上机调试程序,使之能正确运行并得到正确的结果。对这两种继承方式作比较分析,考虑在什么情况下二者不能互相代替。 2. 调试运行Ex1 2.1需求分析: 某小型公司的人员管理信息系统。 三类人员:经理(manager)、技术人员(technician)、销售人员(salesman);后期又增加一类人员:销售经理(sales_manager)。 要求存储这些人员的姓名、编号、级别、当月工资、计算月薪总额并显示全部信息。 (1)人员编号:基数为1000,每增加一名人员时,人员编号加1; (2)人员级别:所有人员初始级别为1,然后进行升级。升级规则:经理为4级、技术人员为3级、销售人员为1级、销售经理为3级; (3)月薪计算:经理=固定月薪8000元;技术人员=100元/小时; 销售人员=当月个人销售额*4%;销售经理=固定月薪5000+所辖部门当月销售额*5%。 2.2数据结构: struct employee { char *name; /* 人员姓名*/ int indiveidualEmpNo; /* 人员编号*/ int grade; /* 人员级别*/

实验四继承与派生

实验四派生类与继承 【实验类型】验证性实验【实验课时】2学时 【实验目的】 (1)理解类的继承的概念,能够定义和使用类的继承关系。 (2)掌握派生类的声明与定义方法。 (3)熟悉公有派生和私有派生的访问特性。 (4)学习虚基类在解决二义性问题中的作用。 【实验环境】 硬件:计算机 软件:Microsoft Visual C++ 6.0 【实验内容】 1、按要求阅读、编写、调试和运行以下程序。 (1)实验内容 ①定义一个基类MyArray,基类中可以存放一组整数。 class MyArray {public: MyArray(int leng); ~MyArray(); void Input(); void Display(); protected: long int *alist; // 指向动态申请的一组空间 int length;}; // 整数的个数 基类中有构造函数、析构函数、输入数据和输出数据的函数。 ②定义一个类SortArray继承自MyArray ,在该类中定义函数实现排序功能。 ③定义一个类ReArray继承自MyArray ,在该类中定义函数实现逆转功能。 ④定义一个类AverArray继承自MyArray ,在该类中定义函数Aver求解整数的平均值。 ⑤定义NewArray类,同时继承了SortArray, ReArray和AverArray,使得NewArray 类的对象同时具有排序、逆转、和求平均值的功能。在继承的过程中声明为虚基类,体会虚基类在解决二义性问题中的作用。 (2)实验程序 (参考) 程序如下: #include "iostream.h" #include "process.h" class MyArray {public:

实验2继承与派生讲解

继承与派生实验2 实验目的2.1 类的继承,能够定义和使用类的继承关系。1.熟练掌握派生类的声明与实现方法。2.掌握 3.掌握类构造函数的初始化列表与作用域分辨符的使用方法。虚基类在解决二义性问题中的作用。 4.理解2.2 实验工具与准备工作在开始实验前,应回顾或复习相关内容。 Visual C++ 6.0等集成开发环境软件。需要一台主算机,其中安装有 2.3 实验内容 1.先阅读下列程序,写出执行结果。然后输入程序,调试程序,比较结果的正确性。 // 文件名: main.cpp #include // 预处理命令 // 使用标准命名空间std using namespace std; class A { public: : 公有函数// ?笩挠畯??尠构造A << endl; } // 构造函数 // A << endl; } 析构函数???潣瑵?? 析构}; class B: public A { public: : 公有函数// // 构造函数B << endl; } ?笩挠畯??尠构造// 析构B << endl; } 析构函数???潣瑵?? }; class C: public B { public: : // 公有函数// 构造函数C << endl; } 构造?笩挠畯??尠 C << endl; } 析构???潣瑵?? 析构函数// }; main(void) 主函数// int main(void) { 定义对象C obj; //

,输出系统提示信息调用库函数system( )// system(PAUSE); 0, 返回操作系统// 返回值return 0; } 2.先阅读下列程序,写出执行结果。然后输入程序,调试程序,比较结果的正确性。// 文件名: main.cpp #include // 预处理命令 using namespace std; // 使用标准命名空间std class A { protected: // 数据成员: int a; // 数据成员 public: // 公有函数: A(int x): a(x){ } // 构造函数 void Show() const{ cout << a << endl; } // 显示a之值 }; class B { protected: // 数据成员: int b; // 数据成员 public: // 公有函数: B(int x): b(x){ } // 构造函数 void Show() const{ cout << b << endl; } // 显示a与b之值 }; class C: public A, public B { public: // 公有函数: C(int x, int y): A(x), B(y){ } // 构造函数 void Show() const // 显示b之值 { cout << a << , << b << endl; } }; int main(void) // 主函数main(void) {

继承与派生实验报告

计算机科学与技术学院程序设计报告 程序名称:继承与派生(一) 专业:计算机科学与技术 班级:计算机1103班 学号: 姓名: 指导老师: 设计日期:2012年4月13日

实验四继承与派生(一) [实验目的] 1、掌握类继承与派生关系以及实现方法,理解类的层次结构; 2、掌握派生类构造函数初始化基类成员和对象成员的方法; 3、掌握赋值兼容原则,掌握派生类的复制构造函数的定义。 [实验内容与步骤] 题目: 由例题1中的point类和circle类继续派生出cylinder,求其表面积Area. 源程序代码: #include using namespace std; const double PI=3.14159; class point //定义point类 { protected: double x,y; public: point(){x=0;y=0;} point(double xv,double yv) { x=xv;

y=yv; } double area(){return 0;} void show() { cout<<"("<

实验二 类的继承与派生

实验二类的继承与派生 一、实验目的 1. 掌握类的声明和使用。 2. 掌握对象的声明和使用。 3. 掌握具有不同访问属性的成员的访问方式。 4. 观察构造函数和析构函数的执行过程。 5. 学习声明和使用类的继承关系,声明派生类; 6. 熟悉不同继承方式下对基类成员的访问控制; 二.实验内容 1. 设计一个用于人事管理的People(人员)类。考虑到通用性,这里只抽象出所有类型人员都具有的属性:number(编号)、sex(性别)、birthday(出生日期)、 id(身份证号)等等。具有的属性如下:姓名char name[11]、编号char number[7]、性别char sex[3]、生日birthday、身份证号charid[20]。其中“出生日期”声明为一个“日期”类内嵌子对象。用成员函数实现对人员信息的录入和显示。要求包括:构造函数和析构函数、拷贝构造函数、内联成员函数、组合。在测试程序中声明people 类的对象数组,录入数据并显示。 2. 从people(人员)类派生出student(学生)类,添加属性:班号char classNO[7];从people 类派生出teacher(教师)类,添加属性:职务char pship[11]、部门char departt[21]。从student 类中派生出graduate(研究生)类,添加属性:专业char subject[21]、导师teacher adviser;从graduate 类和teacher 类派生出TA(助教博士生)类,重载相应的成员函数,测试这些类。 三 . 实验步骤 1.程序代码 第一题 #include #include using namespace std; class Date //日期类 { private: int year; int month; int day; public: Date(){} //默认构造 Date(int y,int m,int d) //带参构造 { year=y; month=m; day=d; }

C++继承与派生实验报告

应用数学学院信息与计算科学(信息计算)专业 1 班、学号3111008106 姓名吴伟栓教师评定_________________ 实验题目继承与派生 一、实验目的与任务 实验目的: (1)学习声明和使用类的继承关系,声明派生类。 (2)熟悉不同继承方式下对基类成员的访问控制。 (3)学习利用虚基类解决二义性问题。 实验任务: (1)声明一个基类Animal,有私有整型成员变量age,构造其派生类dog,在其成员函数SetAge(int n)中直接给age赋值,看看会有什么问题,把age改为公有成员变量,还会有问题吗?编程试试看。 (2)声明一个基类BaseClass,有整形成员变量Number,构造其派生类 DerivedClass,观察构造函数和析构函数的执行情况。 (3)声明一个车(vehicle)基类,具有MaxSpeed,Weight等成员变量,Run,Stop 等成员函数,由此派生出自行车(bicycle)类,汽车(motorcar)类。自行车(bicycle)类有高度(Height)等属性,汽车(motorcar)类有座位数(SeatNum)等属性。从bicycle 和motorcar派生出摩托车(motocycle)类,在继承过程中,注意把vehicle设置为虚基类。如果不把vehicle设置为虚基类,会有什么问题?编程试试看。 (4)(选做)从实验六中的people(人员)类派生出student(学生)类,添加属性:班号char classNo[7];从people类派生出teacher(教师)类,添加属性:职务char principalship[11]、部门char department[21]。从student类中派生出graduate(研究生)类,添加属性:专业char subject[21]、导师teacherradviser;从graduate类和teacher类派生出TA(助教生)类,注意虚基类的使用。重载相应的成员函数,测试这些类。 二、实验步骤 (1)编写程序声明基类Animal,成员变量age声明为私有的。构造派生类dog,在其成员函数SetAge(int n)中直接对age赋值时,会出现类似以下的错误提示:error

实验二 继承与派生 (完整版)

实验二继承和派生的基本概念 一、实验目的 继承与派生是面向对象的特性,是面向对象程序设计模拟客观世界的手段之一,本实验的内容包括介绍基类与派生关系,通过实验要求掌握以下内容。 1.掌握类继承与派生关系以及实现方法,理解类的层次结构。 2.掌握派生类构造函数初始化基类成员和对象成员的方法。 3.掌握赋值兼容原则,掌握派生类的复制构造函数和赋值运算符的定义。 二、实验内容 1.范例:定义一个继承与派生关系的类体系,在派生类中访问基类成员。先定义一个点类,包含x,y坐标数据成员,显示函数和计算面积的函数成员;以点为基类派生一个圆类, 增加表示半径的数据成员,重载显示和计算面积的函数;定义一个线段类,以两个点类对象作数据成员,定义显示、求面积及长度函数,线段类采用聚合方式,因为有两个端点, 不能用派生方式。编程测试所定义的类体系。 【程序】

cl3=cl1; cout<<"cl3圆面积:"<< cl3.Area()<< endl; cl3.Show(); cout<<"线面积:"<< ln1. Area()<<'\t'<<"线长度:"<< ln1. GetLength()<< endl; ln1.Show(); ln2.Show(); return 0; } 【注意】 在Point 类中,将Line 类定义为友元,便于在Line 类中访问;Point 类的x 和y 定义为Protected 访问权限,便于派生类访问。

注意派生类的构造函数中对基类数据成员的初始化方法(即 Circle(double xv,double yv,double vv):Point(xv,yv)), 以及构造函数中对对象成员的初始化方法(即 Line(double xv1,double yv1,double xv2,double yv2) : start(xv1,yv1),end(xv2,yv2){ } ) 【要求】 (1)建立工程,录入上述程序,改变数据实验之。 (2)修改Point 类的数据成员x ,y 的访问权限为private ,再运行,结果如何? 在Line类和Circle类中无法访问Point类的私有成员x,y. (3)如果不将Line 类设为 Point 类的友元,应采取什么措施?为哪个类增加数据或函数成员? 2.编程:多层派生练习,由上题Point 类和Circle 类继续派生出Cylinder 类。要求计算圆柱体的底面积、侧面积、全面积和体积。 #include #include using namespace std; const float PI=3.14; class Point {friend class Line; protected: double x,y; public: Point() {x=0;y=0;} Point(double xv,double yv) {x=xv;y=yv;} double Area() {return 0;} void Show() {cout<<"x="< #include using namespace std; //设计一个圆类Circle和一个桌子类Table,再设计一个圆桌类Roundtable,它是从前两个类派生出来的。//要求输出圆桌的高度、面积、颜色等数据,其中,类Circle包含数据成员radius和圆面积的成员函数,//类Table包含数据成员height和返回高度的成员函数,类Roundtable再添加数据成员color和相应的成员函数。 class circle { private : int radius; public : double area; circle () { radius=0; } circle (int r)

(C++)实验报告六:继承与派生

实验6 继承与派生 一、实验目的 1.理解继承与派生、单继承与多继承的概念; 2.理解基类与派生类的定义及使用方法,派生类对象的定义与初始化方法; 3.理解继承与派生过程中,把派生类作为基类构成类族的概念及虚基类的概念。 二、实验环境 一台PC机,Windows XP操作系统,Visual C++ 6.0开发环境。 三、实验内容 1、由在校人员类(Person)作为基类派生出学生类(Student): 实验步骤: #include #include using namespace std; class Person{ public: Person(int i,char *n, char s, int a){ ID=i; name=n; sex=s; age=a; }; int getID(){ return ID; } void show(){ cout<<"ID: "<

相关主题
文本预览
相关文档 最新文档