当前位置:文档之家› 继承与派生

继承与派生

继承与派生
继承与派生

一、类的继承与派生

1、三种继承方式:公有、私有、保护

不同继承方式的影响主要体现在:

●派生类成员对基类成员的访问控制

●派生类对象对基类成员的访问控制

实际应用中,公有派生用的最为广泛,私有派生相对较少,而保护派生则极少使用

2、派生类对基类成员的继承与否是固定的,但程序员可以在派生类中对继承来的成员进行调整,包括修改成员的访问属性和覆盖原有的成员。

(1)修改成员的访问属性:通过不同的继承方式可以改变成员的访问方式(2)覆盖原有的成员:在派生类中定义与基类同名的数据成员或具有相同函数名和参数的成员函数。

(3)在派生类中可以增加新的成员,增加的这部分内容体现了派生类对基类功能的扩展。

【例题:】某IT公司有如下类型的技术人员:程序员、项目经理,他们能完成不同的工作。对每类技术人员的描述如下:

项目经理:员工编号、姓名、所在部门、基本工资、项目提成

程序员:员工编号、姓名、所在部门、基本工资、奖金

所有的员工都能输出自己的基本信息,包括员工编号、姓名和所在部门。

所有的员工都能计算自己的工资:其中程序员工资等于基本工资加上奖金;项目经理的工资等于基本工资加上项目提成。

要求:用类的继承与派生机制设计描述上述各类技术人员的类。

源代码如下:

#include

#include

using namespace std;

//定义员工类

class Employee{

protected: //不能定义成private:

int id; //员工编号

string name; //姓名

string department; //所在部门

double base_pay; //基本工资

public:

Employee(int a,string s1,string s2,double p){id=a;name=s1;department=s2;base_pay=p;}; //构造函数EMPLOYEE(){};

void SetID(int i){id=i;}

void SetName(string n){name=n;}

void SetDepartment(string d){department=d;}

void SetBase_pay(double bp){base_pay=bp;}

void PrintInfo(); //显示员工基本信息

double salary(); //计算员工工资};

void Employee::PrintInfo()

{

cout<<"员工编号:"<

cout<<"姓名:"<

cout<<"员工所在部门:"<

}

double Employee::salary(){return base_pay;}

//定义程序员类

class Programmer:public Employee

{

private:

double bonus;

string bm; // 添加新的成员“奖金”

public:

programmer() { };

void SetBonus(double s){bonus=s;}

double salary(){return base_pay+bonus;}

//覆盖从基类继承的已经不再适用的成员函数

/*不能在基类中将base_pay定义成private,否则在这里不能访问,所以要定义成protected*/

};

Programmer::programmer(int a,string n,string bm,double p,double b):A(),employee(a,n,bm,p){bonus=p;}

//定义项目经理类

class ProjectManager:public Employee,public A

{

private:

double commission; // 项目提成

public:

void SetCommission(double c){commission=c;}

double salary(){return base_pay+commission;}

};

void main()

{

//Employee e;

//Programmer e;

ProjectManager e;

e.SetID(110);

e.SetName("john");

e.SetDepartment("开发部");

e.SetBase_pay(2000);

e.SetCommission (1000);

e.PrintInfo();

cout<<"工资是:"<

}

二、继承关系中成员的访问控制

1、公有派生的访问控制

基类中所有成员在公有派生类中保持各个成员的原有访问权限。

其中,基类的私有成员(private)在派生类中仍为私有成员。但派生类不能直接使用基类中的私有成员,只能通过该基类公有的或保护的成员函数间接使用基类中的成员。

2、私有派生的访问控制

基类中公有成员和保护成员在派生类中均变为的,在派生类中可直接使用这些成员,但基类的私有成员与公有派生情况相同,在派生类中不能直接使用。

3、保护派生的访问控制

基类的公有成员和保护成员在派生类中都成为保护成员,基类的私有成员在派生类中仍然是私有成员,且不能被派生类直接访问。

【例如:】用以下代码证明在公有继承中:

(1)基类中的公有成员在派生类中仍然是公有成员

(2)基类中的私有成员在派生类中仍然是私有成员,派生类不能直接使用基类中的私有成员,只能通过基类公有的或保护的成员函数间接使用

基类中的私有成员

(3)基类中的保护成员在派生类中仍然是保护成员

#include

#include

using namespace std;

class base

{

private:

void f1(){cout<<"this is a private"<

void f2(){cout<<"this is a protected"<

void f3(){cout<<"this is a public"<

void test()

{

cout<<"在base内调用公有的f3";

f3();

}

};

//定义一个公有派生类

class sub:protected base{

public:

void subtest()

{

f1();//编译错误

f2();//正确

cout<<"在sub内调用test:"<

test();

f3();

}

};

void main()

{

sub b;

b.f1(); //编译错误,证明基类中的私有成员在派生类中没有变成公有成员

b.f2(); //编译错误,证明基类中的保护成员在派生类中没有变成公有成员

b.f3();

}

三、类层次结构中的构造函数和析构函数

构造函数和析构函数不能被继承,因此每个类需要定义自己的构造函数和析构函数。

1、派生类的构造函数

在派生类对象的成员中,从基类继承下来的成员被封装成基类子对象,派生类的构造函数要对派生类对象和基类子对象的创建负责。因此,派生类构造函数需要隐含的或者显式地调用基类构造函数对基类子对象进行初始化。

派生类的构造函数通常采用初始化成员列表的方式调用基类的构造函数。格式为:

派生类类名::派生类类名(参数):基类1(参数),……,基类n(参数){//派生类新增成员的初始化}

(1)如果基类的构造函数是默认构造函数或是不带参数的构造函数,则在派生类中的构造函数中可以省略对基类的构造函数的调用,系统会自动先执行基类没有参数的构造函数;

(2)如果基类没有不带参数的构造函数,则派生类中必须定义带参数的构造函数并显式调用基类的构造函数;

(3)派生类自己的初始化可在参数列表中完成,也可以在构造函数体内完成;

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

(5)单继承时,派生类构造函数调用的一般顺序如下:

a、调用基类的基类的构造函数

b、调用基类的构造函数

c、执行派生类自己的构造函数

2、派生类的析构函数

在派生类中可以根据需要定义自己的析构函数,用来对派生类中心增加的成员进行清理。派生类中的基类子对象的清理工作仍然由基类的析构函数负责,但需要通过派生类的析构函数去调用基类的析构函数。

由于析构函数无参数、无类型,所以定义派生类的析构函数相对简单。在执行派生类的析构函数时,系统会自动调用基类的析构函数,对基类子对象进行清理。

派生类对象执行析构函数时,各析构函数的调用顺序与构造函数的调用顺序正好相反,其调用顺序如下:

a、调用派生类的析构函数

b、调用基类的析构函数

c、调用基类的基类的析构函数

四、基类与派生类的关系

1、基类与派生类定义的成员的优先关系

#include

#include

using namespace std;

class A

{

protected:

int x;

public:

void show(){cout<<"x="<

};

class B:public A

{

protected:

int x;

public:

int &getx(){return x;}

int &getAx(){return A::x;}

};

void main()

{

B b;

b.getx()=10;

b.getAx()=100;

cout<<"B::x="<

cout<<"A::X="<

}

注意:派生类定义的成员优先于基类中的同名成员

2、类型兼容

对于公有派生类来说,可以将派生类的对象赋值给基类对象,反过来则不可以。

类型兼容是指在公有派生的前提下,一个派生类对象可以作为基类的对象来使用,类型兼容有时也被称作赋值兼容或类型适应。

#include

#include

using namespace std;

class point

{

protected:

int x,y;

public:

point(int a,int b):x(a),y(b){}

void show(){cout<<"(x="<

class circle:public point

{

protected:

double radius;

public:

circle(double r,int x,int y):point(x,y){radius=r;}

//void show(){cout<

void showcircle()

{

cout<<"center of circle is"<

show();

cout<<"r is:"<

}

};

void main()

{

double r=1;

int x1=10,y1=10,x2=2,y2=2;

point p1(x1,y1),*pp;

circle c1(r,x2,y2),*cp;

pp=&p1;

cp=&c1;

cp->showcircle ();

pp->show ();

pp=cp; //将派生类对象指针赋值给基类对象//p1=c1;

pp->show();

pp=&c1; //将派生类对象地址赋值给基类对象pp->show();

}

思考:

如果main函数中出现下面的语句,程序会怎样?为什么?cp=pp;

cp->showcircle();

cp=&p1;

cp->show();

五、多继承

1、多继承的构造函数和析构函数

构造函数的调用顺序如下:

a、调用各基类的构造函数。调用顺序按照派生类定义时声明基类的顺

序进行,依次从左至右调用各个基类的构造函数

b、调用内嵌成员对象的构造函数

c、调用派生类的构造函数

析构函数顺序刚好相反。

2、多继承的歧义性与解决办法

情况一:

例如:

class A

{

public:

void print();

……

};

class B

{

public:

void print();

void fun();

……

};

class C:public A,public B

{

X a;

public:

void fun();

//void print();

……

};

定义:C c1; c1.fun(); c1.print();发生歧义

解决办法:

c1.fun();

c1.B::fun();

c1.A::print();

c1.B::print();

歧义情况二:

class A

{

public:

int a;

};

class B:public A

{

public:

int b;

};

class C:public A

{

public:

int c;

};

class D:public B,public C

{

……

//Public :int a;

};

如下发生歧义:

D d; d.a d.A::a;

解决办法:d.B:;a; d.C::A

c++实验8 继承与派生上机练习题

1.定义一个哺乳动物类Mammal,并从中派生出一个狗类Dog,下面给出Mammal类的定义,要求: (1)添加Dog类的颜色数据成员,访问属性为私有,通过SetColor和GetColor成员函数来对颜色进行设置和获取。 (2)分别为基类和派生类添加相应的构造函数(有参、无参)和析构函数,并进行测试。 class Mammal { protected: int itsAge; int itsWeight; public: int GetAge(){return itsAge;} void SetAge(int age) {itsAge=age;} int GetWeight() { return itsWeight;} void SetWeight(int weight) {itsWeight= weight;} }; class Dog : public Mammal { //定义Dog类的数据成员和成员函数 }; 改: #include #include using namespace std; class Mammal { protected: int itsAge; int itsWeight; public: Mammal(); ~Mammal(); int GetAge(){return itsAge;} void SetAge(int age) {itsAge=age;} int GetWeight() { return itsWeight;} void SetWeight(int weight) {itsWeight= weight;} }; class Dog : public Mammal {

继承和派生实验报告

实验目的与要求: 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="< using namespace std; int main() { Teacher t1; t1. inputData (); t1. showData (); return 0; }

实验六继承与派生

继承与组合 一、实验目的 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..."<

类的继承与派生

类的继承与派生 编写一个程序设计一个汽车类vehicle,包含的数据成员有车轮个数wheels 和车重weight。小车类car是它的派生类其中包含载人数passenger_load。卡车类truck是vehicle的派生类其中包含载人数passenger_load和载重量payload,每个类都有相关数据的输出方法. 提示:vehicle类是基类由它派生出car类和truck类将公共的属性和方法放在vehicle类中。 输出结果: 车型:小车 车轮:4个 重量:2000公斤 载人:5人 车型:卡车 车轮:10个 重量:8000公斤 载人:3人 参考代码: #include class vehicle // 定义汽车类 { protected: int wheels; // 车轮数

float weight; // 重量 public: vehicle(int wheels,float weight); int get_wheels(); float get_weight(); float wheel_load(); void show(); }; class car:public vehicle // 定义小车类 { int passenger_load; // 载人数 public: car(int wheels,float weight,int passengers=4); int get_passengers(); void show(); }; class truck:public vehicle // 定义卡车类 { int passenger_load; // 载人数 float payload; // 载重量 public: truck(int wheels,float weight,int passengers=2,float max_load=24000.00); int get_passengers(); float efficiency(); void show(); }; vehicle::vehicle(int wheels,float weight) { vehicle::wheels=wheels; vehicle::weight=weight;

实验二 类的继承与派生

实验二类的继承与派生 班级:网络工程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; }

派生与继承实验1

实验二继承与派生——教师工资计算(一) 一、实验目的 1.理解继承的含义; 2.学习从现有类派生出新类的方式; 3.了解在派生类中如何使用基类的成员。 二、实验内容与要求 1.新建一个雇员类,它的数据成员有雇员代号,年龄,工资,性别,姓名,输入雇员资料方法,打印雇员资料方法。 2.以此雇员类为基类,从中派生出教师类,其中要求在教师类中加入一个计算教师工资的方法,教师工资=基本工资(1000)+课时(月工作量)×30。 3.以此雇员类为基类,从中派生出实验员类,其中要求在实验员类中加入一个计算实验员工资的方法,实验员工资=基本工资(800)+实验室补助(150)+值班时间(月工作量)×5。 4. 以此雇员类为基类,从中派生出行政人员类,其中要求在行政人员类中加入一个计算行政人员工资的方法,行政人员工资=基本工资(900)+行政补贴(200)。 三、实验任务分解 四、实验步骤 1. 建立工程 (1) 新建一个win32 Console Application的工程: 打开VC++开发软件,从[文件]菜单中点击[新建]菜单项,出现如图所示: 在右上角的工程下输入该工程的名称,如 c10,并设置该工程所保存的路径。 最后点击确定。

(2) 当确定后会出现要你选择工程类型的对话框,如图所示:请选择一个空的工程,即 第一个选项。 (3) 当单击确定后,工程建立完毕,接下来建立程序源文件,请再单击[文件]菜单下的[新 建]出现原先出现的对话框,请选择“文件”选项卡中的c++ source file选项,并取名,如c10 (4)当确定后,就进入了源代码的编辑窗口,如图所示:

继承与派生练习题

继承与派生练习题

习题八 第八章继承与派生 1.下列对派生类的描述中,(D.派生类中继承的基类成员的访问权限到派生类保持不变 )是错误的。 A.一个派生类可以作为另一个派生类的基类 B.派生类至少有一个基类 C.派生类的成员除了它自己的成员外,还包含了它的基类成员 D.派生类中继承的基类成员的访问权限到派生类保持不变 2. 派生类的对象对它的哪一类基类成员是可以访问的?(A.公有继承的基类的公有成员) A.公有继承的基类的公有成员 B. 公有继承的基类的保护成员 C. 公有继承的基类的私有成员 D. 保护继承的基类的公有成员 3. 关于多继承二义性的描述,(D.派生类和它的基类中出现同名函数时,将可能出现二义性 )是错误的。

A.派生类的多个基类中存在同名成员时,派生类对这个成员访问可能出现二义性B.一个派生类是从具有共同的间接基类的两个基类派生来的,派生类对该公共基类的访问可能出现二义性 C.解决二义性最常用的方法是作用域运算符对成员进行限定 D.派生类和它的基类中出现同名函数时,将可能出现二义性 4. 多继承派生类构造函数构造对象时,(B.虚基类的构造函数)被最先调用。 A.派生类自己的构造函数B.虚基类的构造函数 C.非虚基类的构造函数 D.派生类中子对象类的构造函数 5. C++类体系中,能被派生类继承的是( B.虚函数)。 A.构造函数 B.虚函数 C.析构函数 D.友元函数 6. 设有基类定义: class Cbase { private: int a; protected: int b; public: int c; }; 派生类采用何种继承方式可以使成员变量b成为自己的私有成员(A. 私有继承) A. 私有继承 B.保护继承

类的继承与派生综合题

1. 类的继承与派生综合题1 题目描述 定义Staff(员工)类,由Staff分别派生出Saleman(销售员)类和Manager(经理)类,再由Saleman(销售员)类和Manager(经理)类采用多重继承方式派生出新类SaleManager(销售经理)类。 要求: a.在Staff类中包含的数据成员有编号(num)、姓名(name)、出勤率(rateOfAttend)、基本工资(basicSal)和奖金(prize)。在Saleman类中还包含数据成员:销售员提成比例(deductRate)和个人销售额(personAmount),在Manager类中还包含数据成员:经理提成比例(totalDeductRate)和总销售额(totalAmount)。在SaleManager类中不包含其他数据成员。 b.各类人员的实发工资公式如下: 员工实发工资=基本工资+奖金*出勤率 销售员实发工资=基本工资+奖金*出勤率+个人销售额*销售员提成比例 经理实发工资=基本工资+奖金*出勤率+总销售额*经理提成比例 销售经理实发工资=基本工资+奖金*出勤率+个人销售额*销售员提成比例+总销售额*经理提成比例 c.每个类都有构造函数、输出基本信息函数(Output)和输出实发工资函数(OutputWage)。 主函数如下: int main() { Salemanobjsale(101101, "LD", 0.88f, 1200, 800, 0.05f, 10000); Manager objmana(101102, "NXG", 0.90f, 2500, 1000, 0.10f, 20000); SaleManagerobjsalemana(101103, "HDY", 0.99f, 3500, 2000, 0.20f, 100000, 0.20f,150000); objsale.Output(); cout<< "销售员的实发工资:" << " "; cout<

继承与多态习题

继承与多态习题 一.基本概念与基础知识自测题 8.1填空题 8.1.1 如果类α继承了类β,则类α称为(1)类,而类β称为(2)类。(3)类 的对象可作为(4)类的对象处理,反过来不行,因为(5)。如果强制转换则要注意(6)。 答案:(1)基类 (2)派生类 (3)派生类 (4)基类 (5)派生类有一些新成员 (6)只能派生类强制转换为基类 8.1.2 当用public继承从基类派生一个类时,基类的public成员成为派生类的(1)成员, protected成员成为派生类的(2)成员,对private成员是(3)。公有派生可以使其类的(4),所以公有派生是主流。 答案:(1)public成员 (2)protected成员 (3)不可访问 (4)接口不变 8.1.3 利用继承能够实现(1)。这种实现缩短了程序开发的时间,VC++中的(2)很 好地体现了这一点。 答案:(1)代码的复用 (2)MFC编程 8.1.4 一个派生类只有一个直接基类的情况称为(1),而有多个直接基类的情况称为 (2)。继承体现了类的(3)概念,这在MFC中得到了很好表现,MFC中只采用了(4)。 答案:(1)单继承 (2)多重继承 (3)层次 (4)单继承 8.1.5 C++中多态性包括两种多态性:(1)和(2)。前者是通过(3)实现的, 而后者是通过(4)和(5)来实现的。 答案:(1)编译时的 (2)运行时的 (3)函数和运算符的重载 (4)类继承关系 (5)虚函数 8.1.6 在基类中将一个成员函数说明成虚函数后,在其派生类中只要(1)、(2)和

(3)完全一样就认为是虚函数,而不必再加关键字(4)。如有任何不同,则认为是(5)而不是虚函数。除了非成员函数不能作为虚函数外,(6)、(7)和(8)也不能作为虚函数。 答案:(1)同虚函数名 (2)同参数表 (3)同返回类型。如基类中返回基类指针,而派生类中返回派生类指针是允许的 (4)virtual (5)重载 (6)静态成员函数 (7)内联函数 (8)构造函数 8.1.7 纯虚函数定义时在函数参数表后加(1),它表明程序员对函数(2),其本质 是将指向函数体的指针定为(3)。 答案:(1)=0 (2)不定义 (3)NULL 8.2简答题 8.2.1构造函数和析构函数可以继承吗?派生类构造函数各部分的执行次序是怎样的?答:构造函数和析构函数不可以继承。派生类构造函数各部分的执行次序是: 1.调用基类构造函数,按它们在派生类声明的先后顺序,依次调用。 2.调用新增成员对象的构造函数,按它们在类定义中声明的先后顺序,依次调用。 3.派生类的构造函数体中的操作。 8.2.2什么叫派生类的同名覆盖(override)? 答:如果派生类声明了一个和某个基类成员同名的新成员(当然如是成员函数,参数表也必须一样,否则是重载),派生类中的新成员就屏蔽了基类同名成员,类似函数中的局部变量屏蔽全局变量。称为同名覆盖(override)。 8.2.3派生类的析构函数中需完成什么任务?是否要编写对基数和成员对象的析构函数的 调用?为什么? 答:析构函数的功能是作善后工作,析构函数无返回类型也没有参数,情况比较简单。派生类析构函数定义格式与非派生类无任何差异,不要编写对基数和成员对象的析构函数的调用,只要在函数体内把派生类新增一般成员处理好就可以了,因为对新增的成员对象和基类的善后工作,系统会自己调用成员对象和基类的析构函数来完成。 8.2.4为什么要使用虚基类?怎样定义虚基类?用一个实例来解释虚基类在其派生类中的 存储方式。 答:在多重继承是有可能出现同一基类的两个拷贝,为避免这种情况,可使用虚基类。虚基类(virtual base class)定义方式如下: class派生类名:virtual 访问限定符基类类名{...}; class派生类名:访问限定符virtual基类类名{...}; virtual 关键字只对紧随其后的基类名起作用。

继承与派生参考代码

1197: 继承与派生1 Description 请以点类Point为基类派生出一个圆类Circle。圆类Circle的数据成员为r(私有属性,存储圆的半径,圆心的点坐标通过继承点类Point加以实现),成员函数有构造函数Circle、计算圆的面积函数Area、计算圆的周长函数Perimeter和输出函数Display,其中构造函数实现基类和圆类的数据成员的初始化,Display函数实现圆心坐标(利用基类Point的Display实现)、圆的半径、圆的面积(利用Area函数实现)和圆的周长(利用Perimeter函数实现)的输出。请编写圆类的定义及成员函数实现,并在主函数中定义圆类对象,验证各个函数的正确性。说明:圆周率PI的取值为3.14 已知Point类的定义及main代码如下:(不允许改动) class Point { public: Point(double xx,double yy); //constructor void Display(); //display point private: double x,y; //平面的点坐标x,y }; int main() { double x,y,r; cin>>x>>y>>r; //圆心的点坐标及圆的半径 Circle C(x,y,r); C.Display(); //输出圆心点坐标,圆的半径,圆的面积,圆的周长 return 0; } Input Output Sample Input 1.5 2.6 1.8 Sample Output Center:Point(1.5,2.6) Radius:1.8 Area:10.1736 Perimeter:11.304 ************************************************************************** #include using namespace std; class Point { public: Point(double xx,double yy) //constructor

C 第八章继承与派生习题习题解答

第八章继承与多态习题 一.基本概念与基础知识自测题 8.1填空题 8.1.1 如果类α继承了类β,则类α称为(1)类,而类β称为(2)类。(3)类 的对象可作为(4)类的对象处理,反过来不行,因为(5)。如果强制转换则要注意(6)。 答案:(1)基类 (2)派生类 (3)派生类 (4)基类 (5)派生类有一些新成员 (6)只能派生类强制转换为基类 8.1.2 当用public继承从基类派生一个类时,基类的public成员成为派生类的(1)成员, protected成员成为派生类的(2)成员,对private成员是(3)。公有派生可以使其类的(4),所以公有派生是主流。 答案:(1)public成员 (2)protected成员 (3)不可访问 (4)接口不变 8.1.4 一个派生类只有一个直接基类的情况称为(1),而有多个直接基类的情况称为 (2)。继承体现了类的(3)概念,这在MFC中得到了很好表现,MFC中只采用了(4)。 答案:(1)单继承 (2)多重继承 (3)层次 (4)单继承 8.1.6 C++中多态性包括两种多态性:(1)和(2)。前者是通过(3)实现的, 而后者是通过(4)和(5)来实现的。 答案:(1)编译时的 (2)运行时的 (3)函数和运算符的重载 (4)类继承关系 (5)虚函数 8.2简答题(以下习题题号可能和教材不一致!) 8.2.1构造函数和析构函数可以继承吗?派生类构造函数各部分的执行次序是怎样的?答:构造函数和析构函数不可以继承。派生类构造函数各部分的执行次序是: 1.调用基类构造函数,按它们在派生类声明的先后顺序,依次调用。 2.调用新增成员对象的构造函数,按它们在类定义中声明的先后顺序,依次调用。 3.派生类的构造函数体中的操作。 8.2.2什么叫派生类的同名覆盖(override)?

实验五类的继承与派生

第一节类的继承与派生 一、基本概念 继承是面向对象程序设计的一个特性,所谓继承就是在已有类的基础上创建新的类,新类可以从一个或多个已有类中继承成员函数或数据成员,而且新类还可以重新定义或加进新的数据和函数。其中,已有类称为基类或父类,新类称为派生类或子类。 在现实世界中许多事物都具有继承性。例如:“汽车”这个类中包括了许多类型,有运输汽车、专用汽车;运输汽车中又包括客车、货车…….;专用汽车中又包括巡逻车、消防车、救护车……..;所有这些类型的车都具有汽车的共同特性即都有发动机、车身、轮胎等共性,还都是自行驱动的。 而客车和货车又有所不同,客车用来载客,货车用来拉货,它们有自己不同于其它车的特性,这就是继承。我们把汽车称为基类,把运输汽车、客车、货车称为派生类。通过继承,派生类不仅拥有了基类的属性和行为,而且具有不同于它类的自己的特点。 二、派生类的定义与构成 当你去水果店买水果的时候,你经常会发现很多同类水果又有了新的品种。比如,“李子”既小又涩,嫁接在梨树上后长出来的李子却硕大、香甜、清脆,比没有嫁接的李子好吃,但它还是李子家族中的一员;所以,可以认为“嫁接李子”是从“李子”中派生出来的。当然,可以把“李子”嫁接在梨树上,也可以嫁接在苹果树上,结出来的都是“李子”,但是各自味道不同。 所谓派生就是从已有类中产生一个新的子类。 基类就是已存在的可以派生新类的类,如下图中的A、D、E都是基类。 派生类就是由基类派生出来的新类,如下图中的B、C、F都是派生类。

1. 单继承派生类的定义格式 class <派生类名> : <继承方式> <基类名> { 派生类成员的定义; }; 其中,“派生类名”是新定义的一个类的名字,它是从“基类名”中派生的,并且按指定的“继承方式”派生。 例如: class peach 多继承派生类的定义格式 class <派生类名> :<继承方式1> <基类名>,<继承方式2> <基类名>, ……. { 派生类成员的定义; }; 多继承与单继承在定义格式的区别仅在于它们的基类个数不同,单继承的基类只有一个,而多继承的基类有多个,相邻两个基类之间用逗号间隔,每个基类名前都应有一个该基类的继承方式的说明符。 例如: class peach //定义基类:peach { datatype color , shape ;

c++实验8继承与派生上机练习题

1. 定义一个哺乳动物类Mamma,l 并从中派生出一个狗类Dog,要求: ( 1) 添加Dog 类的颜色数据成员,访问属性为私有,通过函数来对颜色进行设置和获取。 ( 2) 分别为基类和派生类添加相应的构造函数(有参、无参) 测试。 class Mammal { protected: int itsAge; int itsWeight; public: int GetAge(){return itsAge;} void SetAge(int age) {itsAge=age;} int GetWeight() { return itsWeight;} void SetWeight(int weight) {itsWeight= weight;} }; class Dog : public Mammal { // 定义Dog 类的数据成员和成员函数 }; 改: #include #include using namespace std; class Mammal { protected: int itsAge; int itsWeight; public: Mammal(); ~Mammal(); int GetAge(){return itsAge;} void SetAge(int age) {itsAge=age;} int GetWeight() { return itsWeight;} void SetWeight(int weight) {itsWeight= weight;} }; class Dog : public Mammal {下面给出Mamma类的定义,SetColor 和GetColor 成员和析构函数,并进行

C++继承与派生类习题

第九章继承与派生类 9.2 典型例题分析与解答 例题1:下列对派生类的描述中,()是错误的。 A.一个派生类可以作为另一个派生类的基类 B.派生类至少有一个基类 C.派生类的成员除了它自己的成员外,还包含了它的基类成员 D.派生类中继承的基类成员的访问权限到派生类保持不变 答案:D 分析:一个派生类可以作为另一个派生类的基类。无论是单继承还是多继承,派生类至少有 成 的成员时可能出现二义性。消除二义性的方法是采用作用域运算符。派生类和它的基类中出现同名函数时,不可能出现二义性。 例题4:多继承派生类构造函数构造对象时,()被最先调用。 A.派生类自己的构造函数 B.虚基类的构造函数 C.非虚基类的构造函数D.派生类中子对象类的构造函数 答案:B 分析:多继承派生类构造函数构造对象时,构造函数的调顺序是:虚基类的构造函数,派生类中子对象类的构造函数,派生类自己的构造函数。

例题5:C++类体系中,能被派生类继承的是()。 A.构造函数B.虚函数C.析构函数D.友元函数答案:B 分析:C++类体系中,构造函数、析构函数和友元函数是不能被派生类继承的. 例题6:设有基类定义: class Cbase { private: int a; protected: int b; public: int c; }; 用派生类中子对象类的析构函数,最后调用基类的析构函数。 例题11:设有以下类的定义: class A class B: protected A class C: private B { int A1; { int b1; { int c1; protected: int A2; protected: int b2; protected: int c2; public: int A3; public: int b3; public: int c3; }; }; }; 请按访问权限写出派生类C中具有的成员。 私有成员: (1)

继承与派生

第7章——继承与派生 一、选择题 1.在c++中,类之间的继承关系具有( )。 (a) 自反性 (b) 对称性 (c) 传递性 (d) 反对称性 2.下列关于类的继承描述中,( )是正确的。 (a) 派生类公有继承基类时,可以访问基类的所有数据成员,调用所有成员函数。 (b) 派生类也是基类,所以它们是等价的。 (c) 派生类对象不会建立基类的私有数据成员,所以不能访问基类的私有数据成员。 (d) 一个基类可以有多个派生类,一个派生类可以有多个基类。 3.当一个派生类公有继承一个基类时,基类中的所有公有成员成为派生类的( )。 (a) public成员(b) private成员(c) protected成员(d) 友员 4.当一个派生类私有继承一个基类时,基类中的所有公有成员和保护成员成为派生类的( )。 (a) public成员(b) private成员(c) protected成员(d) 友员 5.当一个派生类保护继承一个基类时,基类中的所有公有成员和保护成员成为派生类的( )。 (a) public成员(b) private成员(c) protected成员(d)友员 6.不论派生类以何种方式继承基类,都不能直接使用基类的()。 (a) public 成员(b) private成员 (c) protected成员(d) 所有成员 7.下面描述中,错误的是( )。 (a) 在基类定义的public成员在公有继承的派生类中可见,也能在类外被访问。 (b) 在基类定义的protected成员在私有继承的派生类中可见。 (c) 在基类定义的公有静态成员在私有继承的派生类中可见。 (d) 访问声明可以在公有继承派生类中把基类的public成员声明为private成员。 8.在c++中,可以被派生类继承的函数是( = )。 (a) 成员函数(b)构造函数(c) 析构函数(d)友员函数 9.在创建派生类对象时,构造函数的执行顺序是( = )。 (a) 对象成员构造函数—基类构造函数—派生类本身的构造函数 (b) 派生类本身的构造函数—基类构造函数—对象成员构造函数 (c) 基类构造函数—派生类本身的构造函数—对象成员构造函数 (d) 基类构造函数—对象成员构造函数—派生类本身的构造函数 10.当不同的类具有相同的间接基类时,( c )。 (a) 各派生类无法按继承路线产生自己的基类版本 (b) 为了建立惟一的间接基类版本,应该声明间接基类为虚基类 (c) 为了建立惟一的间接基类版本,应该声明派生类虚继承基类 (d) 一旦声明虚继承,基类的性质就改变了,不能再定义新的派生类 二、阅读下列程序,写出执行结果 1. #include using namespace std; class Base { public : void get( int i,int j,int k,int l ) { a = i; b = j; x = k; y = l;

继承和派生习题

继承和派生习题 一、单选题 1.若类A和类B的定义如下: class A { int i,j; public: int geti(){return i;} }; class B: public A { int k; public: void make(){k=i*j;} }; 则上述中,()是非法的表达式。 A.k=i*j B.int k; C.return i; D.void make(); 2.关于公有继承,下列说法错误的是()。 A.基类的公有成员和保护成员被继承后作为派生类的公有成员和保护成员。 B.派生类的其他成员可以直接访问基类的公有成员和保护成员。 C.派生类的对象可以访问基类的私有成员。 D.派生类成员和对象都无法访问基类的私有成员。 3.下列说法中错误的是()。 A.公有继承时基类中的public成员在派生类中仍是public的; B.公有继承时基类中的private成员在派生类中仍是private的; C.私有继承时基类中的public成员在派生类中是private的; D.保护继承时基类中的public成员在派生类中是protected的; 4.在公有继承中,基类中的公有成员作为派生类的()。 A.公有成员 B.私有成员 C.保护成员 D.私有成员函数 5.基类中的()不允许外界访问,但允许派生类的成员访问,这样既有一定的隐藏能力,又提供了开放的接口。 A.公有成员 B.私有成员 C.保护成员 D.私有成员函数 6.在下面的表达式中,不表示虚继承的是()。 A.virtual public

B.public virtual C.public D.virtual 7.设置虚函数的声明中,正确的是()。 A.简化程序 B.消除二义性 C.提高运行效率 D.减少目标代码 8.下面叙述错误的是()。 A.基类的protected成员在派生类中仍然是protected B.基类的protected成员在public派生类中仍然是protected的 C.基类的protected成员在private派生类中是private的 D.基类的protected成员不能被派生类的对象访问 9.派生类的对象对它的基类成员中()是可以访问的。 A.公有继承的公有成员 B.公有继承的私有成员 C.公有继承的保护成员 D.私有继承的公有成员 10.下列对派生类的描述中,错误的是()。 A.一个派生类可以作为另一个派生类的基类 B.派生类至少有一个基类 C.派生类的缺省继承方式是private D.派生类只含有基类的公有成员和保护成员 11.继承具有(),即当基类本身也是某一个类派生类时,底层的派生类也会自动继承间接基类的成员。 A.规律性 B.传递性 C.重复性 D.多样性 12.设有基类定义: class Cbase { private: int a; protected: int b; public: int c; }; 派生类采用何种继承方式可以使成员变量b成为自己的私有成员( ) A.私有继承 B.保护继承

继承与派生的基本概念

深圳大学实验报告 课程名称: C++程序设计 实验项目名称:继承与派生的基本概念 学院:信息工程学院 专业:通信工程 指导教师:张力 报告人:学号: 2011130151 班级: 2班实验时间: 2013年12月4日 实验报告提交时间: 2013年12月30日 教务处制

} void Show(){ cout<<"x="<

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