C++程序设计-第13周 继承与派生(二)

课程首页地址:http://blog.csdn.net/sxhelijian/article/details/7910565

【目的】

1. 进一步掌握类的派生与继承的概念、应用方法
2. 掌握继承方式对成员访问权限的影响
3. 掌握虚基类的用法

第三部分 实践项目
【项目1】理解基类中成员的访问限定符和派生类的继承方式
由下面派生类StudentB对基类StudentA的继承……

#include <iostream>
using namespace std;
class StudentA //(1)修改studentA类中各数据成员和成员函数的访问限定符,并观察发生的现象
{
public:
    StudentA(int n,string nam,char s);
    void showA();
    ~StudentA( ) { }
protected:
    int num;
    string name;
    char sex ;
};

class StudentB: public StudentA //(2)修改此处的继承方式,并观察发生的现象
{
public:
    StudentB(int n,string nam,char s,int a,string ad);
    void showB( );
    ~StudentB( ) { }
private:
    int age;
    string addr;
};

StudentA::StudentA(int n,string nam,char s)
{
    num=n;
    name=nam;
    sex=s;
}
void StudentA::showA()
{
    cout<<"num: "<<num<<endl;
    cout<<"name: "<<name<<endl;
    cout<<"sex: "<<sex<<endl<<endl;
}

StudentB::StudentB(int n,string nam,char s,int a,string ad):StudentA(n,nam,s)
{
    age=a;
    addr=ad;
}
void StudentB::showB( )
{
    cout<<"num: "<<num<<endl;
    cout<<"name: "<<name<<endl;
    cout<<"sex: "<<sex<<endl;
    cout<<"age: "<<age<<endl;
    cout<<"address: "<<addr<<endl<<endl;
}

int main( )  //(3)思考由于访问限定符和继承方式的改变,会引发什么现象的发生,并作出解释
{
    StudentB stud1(10010,"Wang-li",'f',19,"115 Beijing Road,Shanghai");
    StudentB stud2(10011,"Zhang-fun",'m',21,"213 Shanghai Road,Beijing");
    StudentA stud3(20010,"He-xin",'m');
    stud1.showB( );
    stud2.showA( );
    stud3.showA( );
    return 0;
}

(1)尝试改变并运行
  请修改基类中成员的访问限定符和派生类的继承方式,考虑可能的运行结果或可能出现的错误,并在上机时进行验证、对比,达到理解派生类成员的访问属性的目的。
(2)总结
  记录(1)的结果,将出现的错误摘录下来,并加上自己的解释;用自己的话总结确定派生类成员的访问属性的原则,也写到报告博文中。

【项目2】(第11章习题9)分别定义Teacher(教师)类和Cadre(干部)类,采用多重继承方式由这两个类派生出新类Teacher_Cadre(教师兼干部)。要求: 
(1)在两个基类中都包含姓名、年龄、性别、地址、电话等数据成员。 
(2)在Teacher类中还包含数据成员title(职称),在Cadre类中还包含数据成员post(职务),在Teacher_Cadre类中还包含数据成员wages(工资)。 
(3)对两个基类中的姓名、年龄、性别、地址、电话等数据成员用相同的名字,在引用这些数据成员时,指定作用域。 
(4)在类体中声明成员函数,在类外定义成员函数。 
(5)在派生类Teacher_Cadre的成员函数show中调用Teacher类中的display函数,输出姓名、年龄、性别、职称、地址、电话,然后再用cout语句输出职务与工资。

【项目3】在下面一段类的定义中,自行车类的虚基类为车辆类,机动车类的虚基类也为车辆类,摩托车类的基类为自行车类和机动车类,类之间均为公有继承。
(1)根据上面各类间关系的描述,补全下面程序段中空缺的代码
(2)实现程序中声明的成员函数,注意相应操作中的动作发生的条件不能满足时应给出提示。
(3)运行程序,享受开摩托的过程。(请下载资源中一个可执行文件,可以先运行再编程。不必申请驾照,这个摩托车很安全。)
(4)在报告中回答问题:本题中使用虚基类的好处是什么?

#include <iostream>
#include<conio.h>
#include <windows.h>
using namespace std;
enum vehicleStaus {rest, running};  //车辆状态:泊车、行进
class vehicle //车辆类
{
protected:
	int maxSpeed;		//最大车速
	int currentSpeed;	//当前速度
	int weight;			//车重
	vehicleStaus status; //rest-泊车状态;running-行进状态
public:
	vehicle(int maxS, int w); //构造函数,初始时,当前速度总为0且处在停车状态
	void start();  //由rest状态到running, 初速为1
	void stop(); //由running状态到rest, 当前速度小于5时,才允许停车
	void speed_up();  //加速,调用1次,速度加1
	void slow_down(); //减速,调用1次,速度减1,速度为0时,停车
};

class bicycle :_____(1)_________//(1)自行车类的虚基类为车辆类
{
protected:
	double height; //车高
public:
	bicycle(int maxS=10, int w=50, int h=0.7);   //定义构造函数
};

class motorcar : ______(2)__________//(2)机动车类的虚基类也为车辆类
{
protected:
	int seatNum; //座位数
	int passengerNum; //乘客人数
public:
	motorcar(int maxS=150, int w=1500, int s=5, int p=1);   //定义构造函数
	void addPassenger(int p=1);   //增加搭载的乘客,超员要拒载,有人下车时,p为负数。当然车上乘客至少有1个(司机)。只有车停稳后才能上下客。
};

class motorcycle: ______(3)_________ //(3)摩托车类的基类为自行车类和机动车类
{
public:
	//定义构造函数
	motorcycle(int maxS=90, int w=100, int s=3, int p=1, int h=0.7);
	void show(); //显示摩托车的运行状态
};

int main( )
{
	motorcycle m;
	bool end=false;
	while (!end){
		cout<<"请操作:1-启动  2-加速  3-减速  4-有人上车  5-有人下车  6-停车 0-结束"<<endl;
		char keydown= _getch(); //_getch()返回键盘上读取的字符
		switch(keydown)
		{
		case '1':
			cout<<"操作(启动)\t"; m.start(); break;
		case '2':
			cout<<"操作(加速)\t"; m.speed_up(); break;
		case '3':
			cout<<"操作(减速)\t"; m.slow_down(); break;
		case '4':
			cout<<"操作(有人上车)\t"; m.addPassenger(); break;
		case '5':
			cout<<"操作(有人下车)\t"; m.addPassenger(-1); break;
		case '6':
			cout<<"操作(停车)\t"; m.stop(); break;
		case '0':
			end=true; break;
		}
		m.show();
		cout<<endl;
		Sleep(200);  //要包含头文件<windows.h>
	}
	return 0;
}

【项目4】日期时间类
  定义一个日期类Date,数据成员包括年、月、日,SetDate(int y,int m,int d)和PrintDate()函数分别用于设置日期和显示日期;再定义一个时间类Time,数据成员包括时、分、秒,SetTime(int h,int m,int s)和PrintTime()函数分别用于设置时间和显示时间,在此基础上再定义一个日期时间类TimeDate,充分利用已有的两个类,并编写主函数测试所定义的类结构。
  
【项目5(选做)】类的组合与继承
(1)先建立一个Point(点)类,包含数据成员x,y(坐标点);
(2)以Point为基类,派生出一个Circle(圆)类,增加数据成员(半径),基类的成员表示圆心;
(3)编写上述两类中的构造、析构函数及必要的输入输出函数
(4)定义友元函数int locate,判断点p在圆c上、圆c内或圆c外,返回值<0圆内,==0圆上,>0 圆外;
(5)重载关系运算符(6种)运算符,使之能够按圆的面积比较两个圆的大小;
(6)给定一点p,求出该点与圆心相连成的直线与圆的两个交点并输出
下面给出用于测试的main()函数,涉及到的类请自行定义

int main( )
{
	Circle c1(3,2,4),c2(4,5,5);      //c2应该大于c1
	Point p1(1,1),p2(3,-2),p3(7,3);  //分别位于c1内、上、外

	cout<<"圆c1: "<<c1;
	cout<<"点p1: "<<p1;
	cout<<"点p1在圆c1之"<<((locate(p1, c1)>0)?"外":((locate(p1, c1)<0)?"内":"上"))<<endl;
	cout<<"点p2: "<<p2;
	cout<<"点p2在圆c1之"<<((locate(p2, c1)>0)?"外":((locate(p2, c1)<0)?"内":"上"))<<endl;
	cout<<"点p3: "<<p3;
	cout<<"点p3在圆c1之"<<((locate(p3, c1)>0)?"外":((locate(p3, c1)<0)?"内":"上"))<<endl;
	cout<<endl; 

	cout<<"圆c1: "<<c1;
	if(c1>c2) cout<<"大于"<<endl;
	if(c1<c2) cout<<"小于"<<endl;
	if(c1>=c2) cout<<"大于等于"<<endl;
	if(c1<=c2) cout<<"小于等于"<<endl;
	if(c1==c2) cout<<"等于"<<endl;
	if(c1!=c2) cout<<"不等于"<<endl;
	cout<<"圆c2: "<<c1;
	cout<<endl; 

	Point p4,p5;
	crossover_point1(p1,c1, p4, p5);

	cout<<"点p1: "<<p1;
	cout<<"与圆c1: "<<c1;
	cout<<"的圆心相连,与圆交于两点,分别是:"<<endl;
	cout<<"交点: "<<p4;
	cout<<"交点: "<<p5;
	cout<<endl;
	return 0;
}

提示:完成(6)时,借助解析几何的知识,推导出交点坐标,编程序解决即可。

第一部分 阅读程序
1、完成本章课后习题5和习题6中的任务。请自行改造程序,创建验证题目中涉及问题的情境,检验自己的答案是否正确。
习题5代码

#include <iostream>
#include<Cmath>
using namespace std;
class A                   //A为基类
{
public:
	void f1( );
	int i;
protected:
	void f2();
	int j;
private:
	int k;
};

class B: public A            //B为A的公用派生类
{
public:
	void f3( );
protected:
	int m;
private:
	int n;
};

class C: public B              //C为B的公用派生类
{
public:
	void f4();
private:
	int p;
};

int main()
{
	A a1;                         //a1是基类A的对象
	B b1;                         //b1是派生类B的对象
	C c1;                         //c1是派生类C的对象
	return 0;
}

习题6代码 

#include <iostream>
using namespace std;
class A
{
public:
	void f1( );
protected:
	void f2();
private:
	int i;
};

class B: public A
{
public:
	void f3( );
	int k;
private:
	int m;
};

class C: protected B
{
public:
	void f4();
protected:
	int n;
private:
	int p;
};

class D: private C
{
public:
	void f5();
protected:
	int q;
private:
	int r;
};

int main()
{
	A a1;
	B b1;
	C c1;
	D d1;
	return 0;
}

2、完成本章课后习题7和习题8中的任务。请运行程序,并和自己的答案进行对照。
习题7代码

#include <iostream>
using namespace std;
class A
{
public:
	A(){a=0;b=0;}
	A(int i){a=i;b=0;}
	A(int i,int j){a=i;b=j;}
	void display(){cout<<"a="<<a<<" b="<<b;}
private:
	int a;
	int b;
};

class B  : public A
{
public:
	B(){c=0;}
	B(int i):A(i){c=0;}
	B(int i,int j):A(i,j){c=0;}
	B(int i,int j,int k):A(i,j){c=k;}
	void display1()
	{
		display();
		cout<<" c="<<c<<endl;
	}
private:
	int c;
};

int main()
{
	B b1;
	B b2(1);
	B b3(1,3);
	B b4(1,3,5);
	b1.display1();
	b2.display1();
	b3.display1();
	b4.display1();
	return 0;
}

习题8代码

#include <iostream>
using namespace std;
class A
{
public:
	A(){cout<<"constructing A "<<endl;}
	~A(){cout<<"destructing A "<<endl;}
};

class B  : public A
{
public:
	B(){cout<<"constructing B "<<endl;}
	~B(){cout<<"destructing B "<<endl;}
};

class C  : public B
{
public:
	C(){cout<<"constructing C "<<endl;}
	~C(){cout<<"destructing C "<<endl;}
};
int main()
{
	C c1;
	return 0;
}

第二部分 期中测验(在OJ平台上完成)

时间: 2024-09-12 04:24:24

C++程序设计-第13周 继承与派生(二)的相关文章

C++程序设计-第11周 继承与派生

课程首页地址:http://blog.csdn.net/sxhelijian/article/details/7910565 (第10周学校放春假,空一周) [目的]1. 掌握类的派生与继承的概念:2. 学会定义子类,重点是类的构造函数与析构函数 第一部分 阅读程序[程序1]阅读下面的程序,写出程序运行结果,上机时再运行,对比结果是否有差异,仔细领会继承,以及基类.派生类中构造函数的写法及执行过程 #include <iostream> #include <string> usin

C++程序设计-第13周递归函数及银行系统程序设计上机实践项目

回到课程主页,链接:C++程序设计课程主页-2012级 本次上机对应的教学内容:第4章   递归函数.变量的作用域.存储类型 第一部分 练习+上机验证(不必提交上机报告) 阅读下列程序,写出程序的运行结果.上机时运行程序,与你的预期进行对照.理解. 提示:如果对运行结果不理解,请通过单步执行的手段跟踪理解. 1. 两个有递归函数的程序,要求按课堂演示,画出调用过程(1) #include <iostream> using namespace std; void f(int); int main

C02-程序设计基础提高班(C++)第13周上机任务-多态与虚函数

第13周:阅读教材第12章(p395-416),主要内容是多态性,完成第13周上机任务 (回到C02-程序设计基础提高班(C++)学习安排) [任务1]下面给出了基类Animal和main()函数.(1)根据main()函数给出的注释提示,设计出相关的各个类.(2)显然,Animal设计为抽象类更合适,Animal不需要能够实例化,是专门作基类使用的.改造程序,使Animal设计为抽象类,这时main()函数中p = new Animal();将出错,将此行删除.(3)每一个Animal的派生类

后台开发:核心技术与应用实践2.2 继承与派生

2.2 继承与派生 1.?继承与派生的一般形式 继承与派生在C++中也是经常使用的,比如设计一个箱子类可以用以下代码实现: Class CBox{ public:     int volume(){         return height*width*length;     }     void display(){         cout<<height<<endl;         cout<<width<<endl;         cout&l

windows phone (13) 样式继承

原文:windows phone (13) 样式继承  在上一遍文章中已经介绍到可以在Resources集合中定义样式,我们也可以在一个样式上引用其他的样式,这就是继承的概念,使用方法是将引用的样式放置在Style中的BaseOn属性:这里使用到的是xaml标记扩展进行设置,比如这里定义的三个样式:  <phone:PhoneApplicationPage.Resources>        <Style x:Key="tbStyle" TargetType=&quo

《Spring攻略(第2版)》——1.13 继承Bean配置

1.13 继承Bean配置 1.13.1 问题在Spring IoC容器中配置Bean时,你可能拥有超过一个共享某些公用配置的Bean,比如属性和元素中的属性.你常常必须为多个Bean重复这些配置. 1.13.2 解决方案Spring允许你提取公用的Bean配置组成一个父Bean.从父Bean继承而来的Bean称作子Bean.子Bean从父Bean继承Bean配置,包括Bean属性和元素中的属性,避免重复配置.子Bean在必要时也可以覆盖继承的配置. 父Bean可以作为配置模板,也可以同时作为B

类的继承与派生

类的继承与派生 尽管在派生类对象中含有从基类继承而来的成员,但派生类并不能直接初始化这些成员,必须使用基类的构造函数来初始化它的基类成员. 初始化顺序:先初始化基类成员,在初始化自己新增成员. 派生类可以访问基类的公有成员和受保护成员. :: 类的作用域分辨符. 我们可以将基类的指针或引用绑定到派生类对象上,但反过来不行,不存在从基类向派生类的隐式转换. 我们用派生类初始化基类或赋值给基类时,调用的是基类相应的构造函数与赋值运算符函数.   子类成员与父类的同名 输出xy,监视一下变量就一目了然

1年期央票利率连续13周维稳

中国人民银行9月7日公告显示,央行7日上午完成发行560亿元1 年期央票,参考收益率连续第13周维持于2.0929%水平. 央行今日仍未进行28天正回购操作,而1年期央票的发行规模也创下4月底以来的新高. 本周公开市场到期资金达2740亿元,为9月乃至整个三季度最大单周到期资金量,因此,本周1年期央票的放量发行也在市场预料之中.而除非本周3年期央票出现放量,否则本周将仍延续上周的净投放格局. 上周在完成700亿元净投放之后,整个8月公开市场以净回笼1090亿元资金收官,而9月,公开市场到期资金量

C语言及程序设计提高例程-35 使用指针操作二维数组

贺老师教学链接  C语言及程序设计提高 本课讲解 使用指向二维数组元素的指针 #include <stdio.h> int main( ) { int a[3][4]= {1,3,5,7,9,11,13,15,17,19,21,23}; int *p; for(p=a[0]; p<a[0]+12; p++) { printf("%3d ",*p); } return 0; } 使用指向一维数组的指针 #include <stdio.h> int main(