C++实验报告(虚基类)
- 格式:docx
- 大小:43.96 KB
- 文档页数:6
c语言实践报告模板3篇C language practice report template汇报人:JinTai Collegec语言实践报告模板3篇前言:社会实践报告是进行社会实践后需要完成的报告,是指有目的、有组织、有计划的深入实际、深入社会,对完成的社会实践活动的一个总结报告。
本文档根据社会实践报告内容要求展开说明,具有实践指导意义,便于学习和使用,本文档下载后内容可按需编辑修改及打印。
本文简要目录如下:【下载该文档后使用Word打开,按住键盘Ctrl键且鼠标单击目录内容即可跳转到对应篇章】1、篇章1:c语言实践报告范本2、篇章2:c语言实践报告例文3、篇章3:c语言实践报告范文(标准版)篇章1:c语言实践报告范本在科技高速发展的今天,计算机互联网在人们之中的作用越来越突出。
而c语言作为一种计算机的语言,我们学习它,有助于我们更好的了解计算机,与计算机进行交流,因此,c语言的学习对我们尤其重要。
在这个星期里,我们专业的学生在专业老师的带领下进行了c语言程序实践学习。
在这之前,我们已经对c语言这门课程学习了一个学期,对其有了一定的了解,但是也仅仅是停留在了解的范围,对里面的好多东西还是很陌生,更多的在运用起来的时候还是感到很棘手,毕竟,万事开头难嘛。
学习c程序设计语言除了课堂讲授以外,必须保证有不少于课堂讲授学时的上机时间。
因为学时所限,课程不能安排过多的统一上机实验,所以希望学生有效地利用课程上机实验的机会,尽快掌握用c语言开发程序的能力,为今后的继续学习打下一个良好的基础。
为此,我们结合课堂讲授的内容和进度,安排了12次上机实验。
课程上机实验的目的,不仅仅是验证教材和讲课的内容、检查自己所编的程序是否正确,课程安排的上机实验的目的可以概括为如下几个方面:1、加深对课堂讲授内容的理解课堂上要讲授许多关于c语言的语法规则,听起来十分枯燥无味,也不容易记住,死记硬背是不可取的。
然而要使用c语言这个工具解决实际问题,又必须掌握它。
虚基类的应用理学院08信息与计算科学080108010028袁世翰C++背景简介:C++语言是一种优秀的面向对象程序设计语言,它在C语言的基础上发展而来,但它比C语言更容易为人们学习和掌握。
C++以其独特的语言机制在计算机科学的各个领域中得到了广泛的应用。
面向对象的设计思想是在原来结构化程序设计方法基础上的一个质的飞跃,C++完美地体现了面向对象的各种特性。
C++语言是从C语言发展演变而来的一种面向对象的程序设计语言。
C++语言的主要特点表现在两个方面,一是全面兼容C,二是支持面向对象的方法。
面向对象的程序设计(OOP)方法将数据及对数据的操作方法封装在一起,作为一个相互依存、不可分离的整体——对象。
对同类型对象抽象出其共性,形成类。
类中的大多数数据只能用本类的方法进行处理。
类通过一个简单的外部接口与外界发生关系,对象与对象之间通过消息进行通信。
这样,程序模块间的关系简单,程序模块的独立性、数据的安全性具有良好的保障。
同时通过继承与多态性,使程序具有很高的可重用性,使软件的开发和维护都更为方便。
由于面向对象方法的突出优点,目前它已经成为开发大型软件时所采用的主要方法,而C++语言是面向对象的程序设计语言中应用最广泛的一种。
实验内容:如果一个派生类有多个直接基类,而这些直接基类又有一个共同的基类,则在最终的派生类中会保留该间接共同基类的数据成员的多份同名成员。
在引用这些同名成员时,必须在派生类对象后面增加直接基类名,以避免产生二义性。
在一个类中保留间接共同基类的多份同名成员,虽然有时是必要的,可以在不同的数据成员中分别存放不同的数据,也可以通过构造函数分别对它们进行初始化。
但在大多数情况下,这种现象是不希望出现的。
因为保留多份数据成员的拷贝,不仅占用较多的存储空间,还增加了访问这些成员时的困难,容易出错。
而且在实际上,并不需要有多份拷贝。
C++提供虚基类(virtual base class)的方法,使得在间接共同基类时只保留一份成员。
(完整版)c实验报告实验名称: C语言实验报告实验内容:本次实验主要针对C语言编程进行实验。
通过实验的设计和完成,检验和加深对C语言的理解和应用能力。
实验步骤:1. 实验准备在开始实验之前,需要准备好以下必要的工具和材料:- 计算机- C语言编译器(比如GCC、Clang等)- 文本编辑器(比如Notepad++、Sublime Text等)2. 实验环境搭建在计算机上安装C语言编译器,并配置好相应的环境变量。
这样可以在终端或命令提示符中执行相关的C程序。
3. 编写实验代码根据实验要求,使用文本编辑器编写C语言代码。
根据实验的要求和功能需求,合理设计和组织代码结构,包括头文件的引用、变量的定义、函数的声明和定义等。
4. 编译和运行代码在命令行或终端中使用编译器对编写好的C语言代码进行编译,并生成可执行文件。
编译命令的具体格式根据不同的编译器而有所差异,但一般形式如下:```gcc -o output_file input_file.c```其中,"output_file"表示生成的可执行文件名,"input_file.c"表示待编译的C源代码文件名。
编译成功后,通过命令行或终端执行生成的可执行文件,检查程序的运行结果是否符合预期。
5. 实验结果分析根据实际运行结果,对实验数据进行分析和归纳。
可以通过输出结果、打印特定信息或观察程序的行为来判断程序是否正确地实现了预期的功能。
6. 实验总结在实验报告中对本次实验的过程、方法、结果进行总结,并提出实验中遇到的问题和解决方法。
同时,对所学习的C语言相关知识点进行总结和归纳,以加深对相关知识的理解和记忆。
实验结果:通过本次实验的设计和实现,我成功完成了对C语言编程的实验,达到了预期的目标。
通过编写实际的代码,我巩固了对C语言语法和基本概念的理解。
在实验过程中,我遇到了一些问题,通过查阅资料和与同学的讨论,我成功解决了这些问题。
面向对象实验报告08级(2)班 240892223 江晓鹏第五章继承与派生的应用1.一、实验目的(1)理解继承与派生过程中,一个基类派生多个子类的概念及应用。
(2)理解继承与派生过程中,把派生类作为基类构成类族的概念及应用。
(3)理解虚基类的概念。
2.二、实验内容(1)把二维坐标类作为基类派生圆类,再由圆类作为基类派生圆柱体类。
(1)题目要求:声明二维坐标类作为基类派生圆的类,把派生类圆作为基类,派生圆柱体类。
其中基类二维坐标类有数据成员:X、Y坐标值;有成员函数:构造函数实现对基类数据成员的初始化、输出的成员函数,要求输出坐标位置。
派生类圆类有新增数据成员:半径(R);有成员函数:构造函数实现对数据成员的初始化、计算圆面积的成员函数、输出的成员函数,要求输出圆半径(R)。
派生圆柱体类新增数据成员有高(H);新增成员函数有构造函数、计算圆柱体体积的函数、输出所有成员的函数。
(2)代码如下#include <iostream>#include <string>using namespace std;#define pai 3.14;class Grahic{private:int X,Y;public:Grahic(int x,int y){X=x;Y=y;}void showG(){cout<<"X="<<X<<" Y="<<Y;}};class Round:public Grahic{public:int R;double area;public:Round(int x=0,int y=0,int r=0):Grahic(x,y){R=r;}double GetArea(){area=3.14*R*R;return area;}void showR(){showG();cout<<" R="<<R;}};class Cylinder:public Round{public:int H;double Vol;public:Cylinder(int x,int y,int r,int h):Round(x,y,r){H=h;}double GetVolume(){Vol=GetArea()*H;return Vol;}void showC(){showR();cout<<" H="<<H;}};void main(){Grahic g1(3,4);cout<<"坐标输出:";g1.showG();Round r1(3,4,2);cout<<endl<<"圆形输出:";r1.showR();cout<<endl<<"圆形面积"<<r1.GetArea();Cylinder c1(3,4,2,5);cout<<endl<<"圆柱输出:";c1.showC();cout<<endl<<"圆柱体积"<<c1.GetVolume();cout<<endl;}(2)把大学的学生类作为基类,派生博士生类,硕士生类和本科生类。
实验6 继承与派生一、实验目的1.理解继承与派生、单继承与多继承的概念;2.理解基类与派生类的定义及使用方法,派生类对象的定义与初始化方法;3.理解继承与派生过程中,把派生类作为基类构成类族的概念及虚基类的概念。
二、实验环境一台PC机,Windows XP操作系统,Visual C++ 6.0开发环境。
三、实验内容1、由在校人员类(Person)作为基类派生出学生类(Student):实验步骤:#include <iostream>#include <string>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: "<<ID<<endl;cout<<"name : "<<name<<endl;cout<<"sex: "<<sex<<endl;cout<<"age: "<<age<<endl;}private:int ID;string name;char sex;int age;};class Student:public Person{public:Student(int i,char *n,char s,int a,float m,float p,float e,float c):Person(i,n,s,a){math=m;physical=p;english=e;cpp=c;total=math+physical+english+cpp;}void show(){Person::show();cout<<"math: "<<math<<endl;cout<<"physical: "<<physical<<endl;cout<<"english: "<<english<<endl;cout<<"C++: "<<cpp<<endl;cout<<"total: "<<total<<endl;}private:float math,physical,english,cpp,total;};void main(){Person p1(1,"张帅",'M',22);p1.show();cout<<endl;Student s1(9901,"林维",'S',21,65,70,75,88);s1.show();}实验结果:2、由学生类、课程类作为基类,共同派生出选课类。
千里之行,始于足下。
c语言实训报告模板范文C语言实训报告模板范文》一、实训目的和背景本次实训的目的是让学生通过实际操作和实践,加深对C语言的理解和运用能力,提升对计算机编程的基本功的掌握程度。
C语言作为一种广泛应用于计算机领域的编程语言,精简而强大,是计算机科学与技术专业的入门必备技能。
二、实训任务和计划本次实训的主要任务是实现一个学生成绩管理系统。
通过该系统,可以方便地输入学生的成绩信息,进行成绩的添加、修改、查询、删除等操作,展示出学生成绩的统计情况,提高学生的学习积极性和教师的成绩管理效率。
具体实训计划如下:1. 学习和复习C语言的基本语法和数据类型,了解输入输出函数的使用方法。
2. 设计学生成绩管理系统的结构和功能,包括输入学生信息、显示学生信息、添加学生成绩、修改学生成绩、查询学生成绩等功能。
3. 使用C语言编写学生成绩管理系统的代码,包括主函数和各个子函数。
4. 进行系统的测试和调试,确保学生成绩管理系统的正常运行。
第1页/共3页锲而不舍,金石可镂。
三、实训过程及心得体会在实训过程中,首先我们需要了解和掌握C语言的基本语法和数据类型,这是编写代码的基础。
我们通过学习教材和参考资料,通过书写简单的代码实例来熟悉C语言的语法规则和运行方式。
然后,我们对学生成绩管理系统进行系统设计和功能划分。
根据需求,我们确定了学生信息的输入和显示功能,以及成绩的添加、修改、查询等功能。
根据这些功能,我们开始编写相应的函数代码,保证系统的正常运行。
在实践中,我们遇到了许多问题和困难。
例如,在输入学生成绩时,如何检查输入的成绩是否合法?在查询学生成绩时,如何展示成绩的排名和统计信息?通过充分的探索和实践,我们运用了C语言的逻辑判断和循环语句,解决了这些问题。
最后,在系统的测试和调试阶段,我们发现了一些代码逻辑上的错误和漏洞,并及时进行了修正。
通过不断地尝试和改进,我们使得学生成绩管理系统达到了我们预期的功能和效果。
C++程序实验报告实验五继承与派生实验目的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)类有座位数(SeatNun)等属性。
从bicycle和motorcar派生出摩托车(motorbicycle)类,在继承进程中,注意把vehicle设置为虚基类。
假设是不把vehicle设置为虚基类,会有什么问题?编程尝试。
实验内容及实验步骤1.编写程序概念基类Animal,成员变量age概念为私有的。
构造派生类dog,在其成员函数SetAge(int n)中直接对age赋值时,会显现类似以下的错误提示:error C2248 : ‘age’ : cannot access private member declared in class ‘Animal’error C2248 : ‘age’ : cannot access private member declared in class ‘Animal’把age改成公有成员变量后从头编译就可以够够够够了。
程序名:。
错误代码:#include<iostream>using namespace std;class Animal{private:int age;public:Animal(){};};class dog:public Animal {public:void SetAge(int n){age=n;};};int main(){dog one;(23);return 0;}运行结果:正确代码:#include<iostream> using namespace std;class Animal{public:int age; public:Animal(){};};class dog:public Animal{public:void SetAge(int n){age=n;};};int main(){dog one;(23);return 0;}运行结果:2.编写程序概念一个基类BaseClass,构造其派生类DerivedClass,在构造函数和析构函数顶用cout输出提示信息,观看构造函数和析构函数的执行情形。
实验目的:通过本次实验,加深对多态和虚函数的理解,掌握在C++中使用虚函数实现多态的方法,并了解虚函数表在多态中的作用。
实验环境:操作系统:Windows 10编译器:Visual Studio 2019编程语言:C++实验内容:本次实验主要涉及以下内容:1. 定义基类和派生类,实现虚函数。
2. 通过基类指针调用虚函数,观察多态现象。
3. 分析虚函数表在多态中的作用。
实验步骤:步骤一:定义基类和派生类首先,定义一个基类`Animal`和一个派生类`Dog`和`Cat`。
```cppinclude <iostream>using namespace std;// 基类Animalclass Animal {public:virtual void makeSound() {cout << "Animal makes a sound" << endl;virtual ~Animal() {}};// 派生类Dogclass Dog : public Animal {public:void makeSound() override {cout << "Dog barks" << endl;}};// 派生类Catclass Cat : public Animal {public:void makeSound() override {cout << "Cat meows" << endl;}};```步骤二:使用基类指针调用虚函数定义一个基类指针,指向派生类对象,并调用虚函数`makeSound()`。
```cppint main() {Animal animal1 = new Dog();Animal animal2 = new Cat();animal1->makeSound(); // 输出:Dog barksanimal2->makeSound(); // 输出:Cat meowsdelete animal1;delete animal2;return 0;}```通过以上代码,我们可以观察到多态现象:基类指针`Animal`指向了派生类对象`Dog`和`Cat`,调用`makeSound()`时,分别输出了不同的结果。
南京航空航天大学实验报告课程名称:虚拟现实技术实验项目:基于OpenGL的C语言虚拟现实建模专业班级:导航、制导与控制姓名:学号:实验时间:成绩:南京航空航天大学实验报告1.实验目的:了解基于OpenGL函数库的C语言虚拟现实三维建模技术,掌握OpenGL主要核心函数库的编程应用方法。
2.实验内容:在Visual C++环境或其他C语言集成设计环境下,建立基于OpenGL建模的编程环境,完成某一场景的建模并正确编译和运行。
3. 实验方案(程序设计方案)本实验实现OpenGL下的时钟,时钟和系统时间同步。
了解并学习OpenGL标准图形库,并通过运用其基本函数实现和系统同步的时钟。
5.实验过程与结果步骤一:在VC下创建clock工程打开VC6.0++ 工程后,找到file->new->Prejects->Win32 Console Application。
设置相应的工程名为clock,并设置好路径,创建一个空工程。
步骤二:加入对应的库文件和头文件把opengl32.lib glu32.lib glaux.lib GL/glut32.lib加入到Setting->Link中,并在代码工程中包含头文件。
如下图所示:图1 加入OpenGL库后的工程步骤三:编写时钟代码1)编写myDisplay函数实现钟的显示,函数中用到的主要OpenGL函数如下:glVertex2f函数进行绘图,由点构成面或者线,从而构成钟面和指针;glColor3f函数修改会制图形的颜色;Localtime函数获取系统时间;2)在main函数中设置Window窗口的大小,位置,调用glutMainLoop循环显示钟表。
运行结果:观察时钟的运行时间,发现和系统运行时间一致,表明此工程已经成功。
图1时钟运行6.出现的问题及解决方法过程中出现的问题:(1)cannot open file "OpenGL/glut32.lib"解决办法:引起这个问题的原因是应为库的路径没有加对,在了解错误原理后,重新设置库文件路径。
C++ 虚基类9/3/2001 8:22:51· ·--··pcvc1 2 下一页在《多继承》中讲过的例子中,由类A,类B1和类B2以及类C组成了类继承的层次结构。
在该结构中,类C的对象将包含两个类A的子对象。
由于类A是派生类C两条继承路径上的一个公共基类,那么这个公共基类将在派生类的对象中产生多个基类子对象。
如果要想使这个公共基类在派生类中只产生一个基类子对象,则必须将这个基类设定为虚基类。
虚基类的引入和说明前面简单地介绍了要引进虚基类的原因。
实际上,引进虚基类的真正目的是为了解决二义性问题。
虚基类说明格式如下:virtual <继承方式><基类名>其中,virtual是虚类的关键字。
虚基类的说明是用在定义派生类时,写在派生类名的后面。
例如:class A{public:void f();protected:int a;};class B : virtual public A{protected:int b;};class C : virtual public A{protected:int c:};class D : public B, public C{public:int g();private:int d;};由于使用了虚基类,使得类A,类B,类C和类D之间关系用DAG图示法表示如下:A{ f(), a }/ \B{b} C{c}\ /D{g(),d}从该图中可见不同继承路径的虚基类子对象被合并成为一个对象。
这便是虚基类的作用,这样将消除了合并之前可能出现的二义性。
这时,在类D的对象中只存在一个类A的对象。
因此,下面的引用都是正确的:D n;n.f(); file://对f()引用是正确的。
void D::g(){f(); file://对f()引用是正确的。
}下面程序段是正确的。
D n;A *pa;pa = &n;其中,pa是指向类A对象的指针,n是类D的一个对象,&n是n对象的地址。
第 1 次实验(2015年6月9日)实验7 继承性和派生类-多基继承(2学时)一、实验目的1.掌握多基继承的使用,访问方法;2.理解类层次中访问规则;3.掌握虚基类的定义及使用。
二、实验内容1.定义一个学生类Student和教师类Teacher,学生类有姓名、学号、私有数据成员,教师类有姓名、工作证号、职称、课程、周学时数。
再定义一个助教类TA,继承学生类和教师类,该类可以使用学生类的全部数据成员,以及教师类的课程和周学时数的数据成员。
要求:每个类提供自定义的构造函数和析构函数,并通过同名函数ShowInfo来显示全部数据成员的值。
三、具体实验过程1.①程序源代码如下:#include <iostream>#include <string>using namespace std;class Student{private:string sname;int snum;public:Student(){sname="Chandra";snum=0;}Student(string a,int b){sname=a;snum=b;}~Student(){cout<<"Destructor called for Student."<<endl;}void show(){cout<<"姓名:"<<sname<<","<<"学号:"<<snum<<endl;} };class Teacher{private:string tname;string tnum;string title;string lesson;int hour;public:Teacher(){tname="zero";tnum="zero";title="zero";lesson="zero";hour=0;}Teacher(string c,int d,string e,string f,int g){tname=c;tnum=d;title=e;lesson=f;hour=g;}~Teacher(){cout<<"Destructor called for Teacher."<<endl;}void show(){cout<<"姓名"<<tname<<",工作证号:"<<tnum<<",职称:"<<title<<",课程:"<<lesson<<",周学时:"<<hour<<endl;}};class TA:public Student,public Teacher{public:TA(){cout<<"调用TA无参构造函数"<<endl;}TA(string a,int b,string c,int d,string e,string f,intg):Student(a,b),Teacher(c,d,e,f,g){cout<<"调用TA有参构造函数"<<endl;}void show(){Student::show();Teacher::show();}~TA(){cout<<"Destructor called for TA."<<endl;}};int main(){TA x,y("Jerry",20,"Tom",21,"讲师","马克思",4);x.show();y.show();return 0;}②编译过程中出现的问题:在编写程序时,不善于运用字符数组,而且指针方面的知识也不熟悉,以后会加强这方面的学习;③运行结果如图所示:四、本次实验小结本次实验的主要考察内容是多继承的运用,这里涉及的知识面很广,用到的知识也很多,而且这个程序也很重要,我会在完成作业之后继续研究一下这个程序,争取能够完全吸收。
C++_虚基类虚基类1.为什么要引⼊虚基类当某⼀个类的多个直接基类是从另⼀个共同基类派⽣⽽来时,这些直接基类中从上⼀级基类继承来的成员就拥有相同的名称。
在派⽣类的对象中,这些同名成员在内存中同时拥有多个拷贝。
如何进⾏分辨呢?⼀种⽅法就是使⽤作⽤域标⽰符来唯⼀表⽰它们另⼀种⽅法是定义虚基类,使派⽣类中只保留⼀份拷贝。
例虚基类的引例#include <iostream.h>class base {public:base(){ a=5; cout<<"base a="<<a<<endl; }protected:int a;};class base1:public base{public:base1() { a=a+10; cout<<"base1 a="<<a<<endl; }};class base2:public base{public:base2(){a=a+20; cout<<"base2 a="<<a<<endl;}};class derived:public base1,public base2{public:derived() {cout<<"base1::a="<<base1::a<<endl;cout<<"base2::a="<<base2::a<<endl;}};main(){derived obj;return 0;}程序运⾏结果如下:base a=5base1 a=15base a=5base2 a=25base1::a=15base2::a=25⾮虚基类的类层次图2. 虚基类的概念class derived:public base1,public base2{public:derived(){ cout<<"base1::a="<<a<<endl; }}可使⽤虚基类解决上例访问类base成员a的⼆义性问题。
第十三次实验报告:一、1.定义Point类,有坐标x,y两个成员变量,利用友元函数对Point类重载“++”运算符,实现对坐标值的改变。
具体要求如下:(1)编写程序定义Point类,在类中定义整型的私有成员变量x,y;(2)在类中定义两个友元函数,分别重载前置++和后置++;(3)编写主函数测试。
注意函数有无返回值的区别,以及返回值是否带有&应用符号。
实验结果:二、定义Point类,有坐标x,y两个成员变量,利用成员函数对Point类重载”++”运算符,实现对坐标值的改变要求:(1)编写程序定义Point类,在类中定义整型的私有成员变量x,y(2)定义成员函数Point& operator++(); Point operator++(int);以实现对Point类重载”++”运算符,分别重载前置++和后置++(3)编写主函数测试代码:class A{Friend A operator<需要重载的运算符>(参数);A operator<需要重载的运算符>(参数){//代码实现}};A operator <需要重载的运算符>(参数){//代码实现}测试数据:分数2/4结果:三、3.定义一个分数类,通过重载运算符实现分数的四则运算、求负运算和赋值运算。
其中,要求加法“+”和减法“-”用友元函数实现重载,其他运算符用成员函数实现重载。
程序代码:实验结果:四、定义一个车(vehicle)基类,有Run,Stop等成员函数,由此派生出自行车(bicycle)类,汽车(motorcar)类,从bicycle和motorcar派生出摩托车(motorcycle)类,它们都有Run,Stop等成员函数要求:(1)编写程序定义一个车(vehicle)基类,有Run、Stop等成员函数(2)由车(vehicle)基类派生出自行车(bicycle)类,汽车类(motorcar),从bicycle类和motorcar类派生出摩托车类(motorcycle),它们都有Run,Stop等成员函数(3)在main()函数中定义vehicle,bicycle,motorcar,motorcycle的对象,调用其Run(),Stop()函数,观察其执行情况(4)分别用vehicle类型的指针来调用几个对象的成员函数,看看能否成功(提示:把Run,Stop定义为虚函数)代码:class A{//代码实现};class B: public virtual A{//代码实现};class C: public virtual A{//代码实现};class D: public virtual B, public virtual C{//代码实现};测试数据:1在主函数分别创造了vehicle, bicycle, motorcar, motorcycle 并执行各自的Run 、Stop 成员函数2在主函数创造了一个vehicle 类型的指针,分别用该指针指向基类和派生类的Run 、Stop 成员函数结果:由于在这题中bicycle 与motorcar 都继承了同一个基类,所以必须使用虚继承,才能时基类vehicle 指针指向motorcycle 对象时,不会报指针指向异常的错误实验结果:五、编写程序,定义抽象基类Container ,由此派生出2个派生类球体类Sphere ,圆柱体类Cylinder ,分别用虚函数分别计算表面积和体积。
我们知道,如果一个派生类有多个直接基类,而这些直接基类又有一个共同的基类,则在最终的派生类中会保留该间接共同基类数据成员的多份同名成员。
在引用这些同名的成员时,必须在派生类对象名后增加直接基类名,以避免产生二义性,使其惟一地标识一个成员,如:c1.A::display( )在一个类中保留间接共同基类的多份同名成员,虽然有时是有必要的,可以在不同的数据成员中分别存放不同的数据,也可以通过构造函数分别对它们进行初始化。
但在大多数情况下,这种现象是人们不希望出现的。
因为保留多份数据成员的拷贝,不仅占用较多的存储空间,还增加了访问这些成员时的困难,容易出错。
而且在实际上,并不需要有多份拷贝。
C++提供虚基类(virtual base class)的方法,使得在继承间接共同基类时只保留一份成员。
假设类D是类B和类C公用派生类,而类B和类C又是类A的派生类,如图11.21所示。
设类A有数据成员data和成员函数fun;派生类B和C分别从类A继承了data和fun,此外类B还增加了自己的数据成员data_b,类C增加了数据成员data_c。
如果不用虚基类,就会在类D中保留了类A成员data的两份拷贝,分别表示为int B::data和int C::data。
同样有两个同名的成员函数,表示为void B::fun()和void C::fun()。
类B 中增加的成员data_b和类C中增加的成员dat_c不同名,不必用类名限定。
此外,类D还增加了自己的数据成员data_d和成员函数fun_d。
图11.21现在,将类A声明为虚基类,方法如下:.class A //声明基类A.{.// 代码.};.class B: virtual public A //声明类B是类A的公用派生类,A是B的虚基类.{.// 代码.};.class C: virtual public A //声明类C是类A的公用派生类,A是C的虚基类.{.// 代码.};注意: 虚基类并不是在声明基类时声明的,而是在声明派生类时,指定继承方式时声明的。
C++实验报告目录C++实验报告 (1)实验一熟悉Visual C++6.0环境 (2)一、实验目的 (2)二、实验原理 (2)三、实验内容 (2)四、实验思考讨论与心得体会 (6)实验二构造函数和析构函数 (6)一、实验目的 (6)二、实验原理 (7)三、实验程序 (7)四、实验结果及程序分析 (7)五、实验思考讨论与心得体会 (8)实验三常类型与类型转换 (8)一、实验目的 (8)二、实验原理 (9)四、实验结果及程序分析 (10)五、实验思考讨论与心得体会 (11)实验四派生类的构造函数与虚基类 (11)一、实验目的 (12)二、实验原理 (12)三、实验程序 (13)四、实验结果及程序分析 (14)五、实验思考讨论与心得体会 (15)实验五运算符重载 (15)一、实验目的 (16)二、实验原理 (16)三、实验程序 (16)四、实验结果及程序分析 (20)五、实验心得体会 (20)实验六动态联编 (21)一、实验目的 (21)二、实验原理 (21)三、实验程序 (21)四、实验结果及程序分析 (23)五、实验思考讨论与心得体会 (23)实验七扑克牌游戏程序设计 (24)一、实验目的 (24)二、实验原理 (24)三、实验程序 (24)四、实验思考讨论与心得体会 (27)实验一熟悉Visual C++6.0环境一、实验目的1. 熟悉实验设备、环境; 熟练掌握Visual C++6.0环境;2.掌握调试程序的操作步骤;初步了解程序的结构。
二、实验原理使用C++语言编写源程序后,源程序在计算机上的实现与其它高级语言源程序实现的原理是一样的一般都要经过下述三个步骤:(1)编辑:即将编写好的C++源程序输入到计算机当中,生成磁盘文件的过程。
(2)编译:C++语言的编译器可将程序的源代码转换成为机器代码的形式即目标代码,然后再对目标代码进行连接,生成可执行文件,等待下一步的执行过程。
(3)运行:即在编译系统中运行源程序经过编译和连接后生成的可执行文件。
实验六实验目的1.掌握运算符重载的方法2.学习使用虚函数实现动态多态性实验要求1.定义Point类,有坐标_x,_y两个成员变量;对Point类重载“++”(自增)、“――”(自减)运算符,实现对坐标值的改变。
2.定义一个车(vehiele)基类,有Run、Stop等成员函数,由此派生出自行车(bicycle)类、汽车(motorcar)类,从bicycle和motorcar派生出摩托车(motorcycle)类,它们都有Run、Stop等成员函数。
观察虚函数的作用。
3. (选做)对实验4中的People类重载“==”运算符和“-”运算符,“==”运算符判断两个people类对象的id属性是否相等;“-”运算符实现People类对象的赋值操作。
实验内容及实验步骤1.编写程序定义Point类,在类中定义整型的私有成员变量_x_y,定义成员函数Point& operator++();Point operator++(int);以实现对Point类重载“++”(自增)运算符,定义成员函数Point& operator--();Point operator--(int);以实现对Point 类重载“--”(自减)运算符,实现对坐标值的改变。
程序名:1ab8_1.Cpp#include <iostream>using namespace std;class Point{public:Point();Point(int x,int y);~Point(){} //Point类析构函数Point& operator++(); //公有成员函数Point operator++(int);Point&operator--();Point operator--(int);void Show();private:int _x; //私有数据成员int _y;};Point::Point(){ //Point类构造函数_x=0;_y=0;}Point::Point(int x,int y) //Point类构造函数{_x=x;_y=y;}Point & Point::operator++() //重载后置++运算符为Point类成员函数{_x++;_y++;}Point Point::operator++(int) //重载前置++运算符为Point类成员函数{Point old=*this;++(this->_x);++(this->_y);return old;}Point & Point::operator--() //重载后置--运算符为Point类成员函数{_x--;_y--;}Point Point::operator--(int) //重载前置--运算符为Point类成员函数{Point old=*this;--(this->_x);--(this->_y);return old;}void Point::Show() //输出Point的坐标值{cout<<_x<<","<<_y<<")"<<endl;}int main(){Point a(2,3); //定义一个Point类对象aPoint b=a++; //定义Point类对象b并用a++初始化b Point c=++a; //定义Point类对象c并用++a初始化c Point d=--a; //定义Point类对象d并用--a初始化d Point e=a--; //定义Point类对象e并用a--初始化e cout<<"Point a(";a.Show(); //输出a的坐标cout<<"Point b(";b.Show(); //输出b的坐标cout<<"Point c(";c.Show(); //输出c的坐标cout<<"Point d(";d.Show(); //输出d的坐标cout<<"Point e(";e.Show(); //输出e的坐标return 0;}运行结果:2编写程序定义一个车(vehicle)基类,有Run、Stop等成员函数,由此派生出自行车(bicycle)类、汽车(motorcar)类,从bicycle和motorcar派生出摩托车(motorcycle)类,它们都有Run、Stop等成员函数。
实验五 Shape虚基类
一、实验目的
1.掌握虚基类的定义、使用
2.理解使用虚函数和继承类实现多态性
二、实验环境
Windows + VC++6.0。
三、实验内容及要求
定义抽象基类Shape,有它派生出三个类:Circle、Rectangle、Triangle,用函数ShowArea 分别显示各种图形的面积,最后还要显示所有的图形面积。
要求用基类指针数组,使他的每一个元素指向一个派生类对象。
四、实验步骤
(1) 定义一个虚基类Shape,在ShowArea函数声明前冠以virtual使其成为虚函数,并且能够在派生类中重定义。
(2)定义三个派生类Circle、Rectangle、Triangle,并公有继承Shape基类。
(3)在主函数中分别调用三个派生类的ShowArea函数,求出各个形状的面积。
(4)定义一个基类指针数组p[3]={&A,&B,&C},通过->访问派生类对象
的成员函数ShowArea,如p[0]->ShowArea()访问的是对象A的成员函数。
五、程序分析
1.抽象类只能作为基类来使用,其纯虚函数的实现由派生类给出。
如果派生类中没有重新定义纯虚函数,而只是继承基类的纯虚函数,则这个派生类仍然还是一个抽象类。
如果派生类中给出了基类纯虚函数的实现,则该派生类就不再是抽象类了,它是一个可以建立对象的具体的类。
2.如果派生类重写了基类的虚函数,那么编译器对应的操作为将指向虚函数表的指针__vfptr指向的函数指针数组中相应的虚函数入口地址改变为当前派生类实现的函数入口地址;
基类指针指向派生类后,实际上指向的是从基类派生到派生类那段成员的首地址(存放__vfptr,如果定义有虚函数),基类指针在调用虚函数的额时候,是通过查该__vfptr地址指向的函数指针数组来查找函数入口地址。
所以,如果派生类重写了虚函数,那么以上查找的虚函数的入口地址将是派生类重写的函数的入口地址。
六、实验结果与总结
实验总结:
抽象基类与普通基类不同,他平不是现实存在的对象,它可以没有任何物理上的或其他实际意义方面的含义,例如Shape类,只有一个成员函数,没有数据成员。
它既不代表点,也不代表圆。
实验结果如下:
实验总结:
1.抽象基类与普通基类不同,他平不是现实存在的对象,它可以没有任何物
理上的或其他实际意义方面的含义,例如Shape类,只有一个成员函数,没有数据成员。
它既不代表点,也不代表圆。
对于虚函数,在基类用Virtual申明成员函数为虚函数。
这样就可以在派生类中重新定义此函数,为他赋新功能,并能方便的调用。
2.抽象基类是本类族的公共接口。
或者说,从同一基类派生出的多个类有同
一接口。
因此能响应同一形式的消息(例如各类对象都有能对用基类指针调用虚函数作出响应),但是相应的方式因对象不同而异。
在通过虚函数实现动态多动性时,可以不必考虑对象是哪一个类派生出来的,都用同一种方式调用(因为基类指针可以指向同一类组的所有类,因而可通过基类指针调用不同类的虚函数)。
附1:完整的原程序。