继承与派生 - 范文中心

继承与派生

09/14

实验四 继承与派生 一.实验目的及要求

1.掌握单继承和多重继承下派生类的定义方法,理解基类成员在不同的继承方式下不同的访问属性。

2.正确定义派生类的构造函数与析构函数,理解定义一个派生类对象时各个构造函数、析构函数被调用的顺序。

3.正确定义虚基类,消除在多层次继承方式下顶层基类中成员访问的二义性问题,关注此时各构造函数、析构函数的调用顺序。

4.通过基类与派生类的定义,及基类对象、指针、引用与派生类的对象、地址间相互赋值的方法,正确理解赋值兼容的4种情况,通过程序理解其不可逆性。 二.实验内容

在自己的文件夹下建立一个名为exp4的工程,在该工程中做如下操作: 定义一个车基类,派生出自行车类和汽车类,又以自行车类和汽车类为基类共同派生出摩托车类,每个类都要定义带有参数的构造函数。对自行车类继承基类的方式分别用private、protected、public,观察基类成员在派生类中的访问属性;观察自行车类、汽车类和摩托车类对象定义时构造、析构函数的调用顺序。最后将车基类定义为虚基类再观察程序运行结果,具体完成以下要求。

(1)定义基类Vehicle,具有两个保护成员变量:MaxSpeed、Weight,有3个公有的成员函数:Run()、Stop()、Show(),以及带参数构造函数、析构函数;再定义一个从Vehicle公有继承的Bicycle类,增加Height保护属性的成员变量,定义Bicycle类的构造函数、析构函数,改造Show函数,用于输出本类中的完整信息。main()函数中定义Bicycle类对象,观察构造函数和析构函数的执行顺序,以及各成员函数的调用。请用跟踪的方法观察程序运行的每一步究竟调用的是哪一个函数。

(2)在上一步基础上,将继承方式分别修改为protected和private,再重新编译,观察这时的报错信息并能解释。修改程序使程序正确运行。

(3)将Bicycle类的继承方式恢复为public,代码回到(1)的状态,再在Bicycle类下面增加一个第二层汽车类Car的定义,Car也是公有继承基类Vehicle,其中增加了一个保护成员变量SeatNum,表示汽车有几个座位,其定义方式与类Bicycle类似。主函数中定义该对象,观察运行结果。

(4)在上一步的基础上,再定义一个第三层类MotorCycle,该类以公有继承方式继承了第二层的Bicycle和Car类。定义其构造函数,要调用两个直接基类的构造函数,再改造函数Show(),输出所有四个成员变量的信息。主函数中只定义类MotorCycle的对象并调用相应的函数,代码请参考实验指导的(4)。程序进行编译,会产生4个错误、8个警告,因为存在二义性问题,请采用在同名成员前增加“基类名::”以消除二义性直到程序正确,观察运行结果。

(5)再将代码恢复至上一步未修改前,即存在4个错误、8个警告的状态,再作一定的修改,将Vehicle声明为虚基类以消除二义性,同时修改第三层的构造函数,其余代码不变,具体请参考实验指导的(5),观察运行结果,理解此时构造函数、析构函数的调用顺序及用虚基类消除二义性的原理。 三.试验程序及结果 1.

#include using namespace std;

{

public: A(){ cout

class B: public A {

public: B(){ cout

class C: public B {

public: C(){ cout

int main(void) { C obj; system("PAUSE"); return 0; }

2.

#include using namespace std;

{

protected: int a;

public: A(int x): a(x){ } void Show() const{ cout

class B {

protected: int b;

public: B(int x): b(x){ } void Show() const{ cout

class C: public A, public B {

public: C(int x, int y): A(x), B(y){ } void Show() const { cout

int main(void) { C obj(5, 18); obj.Show(); obj.A::Show(); obj.B::Show(); system("PAUSE"); return 0; }

3.

#include using namespace std;

class A {

private: int a; public:

// 公有函数: A(int x): a(x){ } void Show() const { cout

class B: public A {

protected: int b;

public: B(int x, int y): A(x), b(y){ } void Show() const { A::Show(); cout

int main(void) { B obj(5, 18); obj.Show(); system("PAUSE");

}

4.

#include using namespace std; class Base { private: int m; public: Base(int a): m(a){ } Base(const Base &copy) { m = copy.m; } void Show() const { cout

} Derived obj(10, 18); obj.Show(); system("PAUSE"); return 0;

5.

#include using namespace std; /

class Person {

protected: char name[18]; int age; char sex[3]; public: Person(char nm[], int ag, char sx[]) { strcpy(name, nm); age = ag; strcpy(sex, sx); } void Show() const { cout

class Teacher: virtual public Person {

protected: char title[18]; public: Teacher(char nm[], int ag, char sx[], char tl[]): Person(nm, ag, sx)

{ strcpy(title, tl); } void Show() const { Person::Show(); cout

class Cadre: virtual public Person {

protected: char post[18]; public: Cadre(char nm[], int ag, char sx[], char pt[]): Person(nm, ag, sx { strcpy(post, pt); } void Show() const { Person::Show(); cout

class TeacherCadre: public Teacher, public Cadre {

protected: double wages; public: TeacherCadre(char nm[], int ag, char sx[], char tl[], char pt[], double wg) : Person(nm, ag, sx), Teacher(nm, ag, sx, tl), Cadre(nm, ag, sx, pt) { wages = wg; } void Show() const { Person::Show(); cout

int main(void) {

}

Teacher objTeacher("文冠杰", 48, "男", "教授"); Cadre objCadre("周杰", 56, "男", "院长"); TeacherCadre objTeacherCadre("李靖", 50, "女", "教授", "院长", 6890); objTeacher.Show(); objCadre.Show(); objTeacherCadre.Show();

system("PAUSE"); return 0;

6.

#include using namespace std;

class Staff {

protected: // 数据成员: int num; char name[18]; double rateOfAttend; double basicSal ; double prize ; static int count;

public: Staff(){ } void Input() { num = ++count; cout > name; cout > basicSal; cout > prize; cout > rateOfAttend; } void Output() const { cout

int Staff::count = 1000;

class Saleman : virtual public Staff {

protected: float deductRate; float personAmount;

public: Saleman (){ }; void Input( void ) { Staff::Input(); cout > personAmount;

cout > deductRate; } void Output() const { Staff::Output(); cout

class Manager: virtual public Staff {

protected: double totalDeductRate; double totalAmount;

public: Manager(){ } void Input( void ) { Staff::Input(); cout > totalAmount; cout > totalDeductRate; } void Output() const { Staff::Output(); cout

}

};

class SaleManager: public Saleman, public Manager

{

public:

SaleManager(){ };

void Input( void )

{

Staff::Input();

cout

cin >> personAmount;

cout

cin >> deductRate;

cout

cin >> totalAmount;

cout

cin >> totalDeductRate;

}

void Output() const

{

Staff::Output();

cout

cout

cout

cout

}

void OutputWage() const

{

cout

}

};

int main(void)

{

char flag = 'Y';

while (toupper(flag) == 'Y')

{

int n;

cin >> n;

if (n == 1)

{ // 员工

Staff objStaff;

objStaff.Input();

objStaff.Output();

objStaff.OutputWage();

}

else if (n == 2)

{ // 销售员

Saleman objSaleman;

objSaleman.Input();

objSaleman.Output();

objSaleman.OutputWage();

}

else if (n == 3)

{

Manager objManager;

objManager.Input();

objManager.Output();

objManager.OutputWage();

}

else if (n == 4)

{

SaleManager objSaleManager;

objSaleManager.Input();

objSaleManager.Output();

objSaleManager.OutputWage();

}

else

{ // 其它情况, 表示选择有误

cout

}

cout

cin >> flag;

}

system("PAUSE");

return 0;

}

五.实验总结

通过这次实验,我对类的继承和派生,派生类构造函数初始化基类成员和对象成员的方法,以及赋值兼容原则有了更深的理解


相关内容

  • c++--公有继承,私有继承和保护继承
    1.   公有继承(public) 公有继承的特点是基类的公有成员和保护成员作为派生类的成员时,它们都保持原有的状态,而基类的私有成员仍然是私有的. 2.   私有继承(private) 私有继承的特点是基类的公有成员和保护成员都作为派生类 ...
  • 逆向 C -- 识别类及其构造函数 - FISH 的专栏 - CSDNBlog
    逆向 C++ 这些年来,逆向工程分析人员一直是凭借着汇编和 C 的知识对大多数软件进行逆向工程的,但是,现在随着越来越多的应用程序和恶意软件转而使用 C++语言进行开发,深入理解 C++ 面向对象方式开发的软件的反汇编技术就显得越发的必要. ...
  • net互联网软件开发工程师 new-2
    .NET互联网软件开发工程师 岗位描述: 字不能放在变量名首位 8.C# 数组从零开始建立索引,即数组索引从零开始.C# 中数组的工作方式与在大多数其他流行语言中的工作方式类似.但还有一些差异应引起注意. 声明数组时,方括号 ([]) 必须 ...
  • 软件体系结构试题免费版本
    软件体系结构考试试题 1.设计模式一般用来解决什么样的问题( a) A.同一问题的不同表相 B不同问题的同一表相 C.不同问题的不同表相 D.以上都不是 2.下列属于面向对象基本原则的是( c ) A.继承 B.封装 C.里氏代换 D都不是 ...
  • 冲压模具的价格估算
    冲压模具的价格估算 [摘要]对冲压模具的价格估算提出了简介,给出了冲压模具的价格估算考虑的内容及具体的方法,并指出这一估算方法在冲压实际中的应用价值. 关键词:冲压模具 价格 估算 1 引言 冲压模具的价格估算在有关文献中已有论述,但大都给 ...
  • 4-6婚姻法讲稿
    第二章 亲属法律概述 一.亲属法的名称和含义 1.名称 在中国,亲属法作为一个专有名词是从清末修订法律开始的.但亲属一词来源于中国过去的律例,并非译自外国.为方便起见,我们将调整亲属关系的法律统称为亲属法,而不问具体名称为何. 我国现行法律 ...
  • 考博英语词汇记忆方法
    考博英语词汇记忆方法-从阅读记单词 Science,inpractice,dependsfarlessontheexperimentsitpreparesthanonthepreparednessofthemindsofthemenwhow ...
  • 20**年考研政治思修考点:行使法律权利,履行法律义务
    2016考研政治思修考点:行使法律权利,履行法律义务 11月的脚步已经来到了,2016考研即将进入最后的冲刺阶段,最后两个月老师为同学们准备了最精良的"武器弹药",每天用十分钟时间跟着老师把2016考研政治思修中的重难点 ...
  • 中国文学史第四卷考试小结
    <三国演义>的艺术成就 1.虚与实的结合2.非凡的叙事才能3.全景式的战争描写4.特征化性格的艺术典型5.历史演义体语言 <水浒传>的艺术成就 1.白话语体成熟的标志2.同而不同的英雄群像3.传奇性与现实性的结合4. ...
  • 专门化 DITA 主题类型
    中国 [选择] 使用条款 dW 全部内容----------------- AIX and UNIX Information management Lotus Rational Tivoli WebSphere Workplace----- ...