一、实验目的及要求
1)掌握类的定义和使用;掌握类对象的声明;练习具有不同访问属性的成员的访问方式;观察构造函数和析构函数的执行过程;
2)学习类组合使用方法;
3)使用VC++的debug调试功能观察程序流程,跟踪观察类的构造函数、析构函数、成员函数的执行顺序。
二、实验内容
1)编写重载函数Max1可分别求取两个整数,三个整数,两个双精度数,三个双精度数的最大值。
2)写一个函数,具有一个引用作为形参参数,在函数中改变引用变量的值,观察实参变量的变化。
3)定义一个CPU类,包含等级(Rank)、频率(frequency)、电压(voltage)等属性,有两个公有成员函数run、stop。其中,rank为枚举类型CPU__Rank,定义为enum CPU_Rank{P1=1,P2,P3,P4,P5,P6,P7},frequency为单位是MHz的整型数,voltage为浮点型的电压值。观察构造函数和析构函数的调用顺序。
4)定义一个简单的Computer类,有数据成员芯片(cpu)、内存(ram)、光驱(cdrom)等等,有两个公有成员函数run、stop。cpu为CPU类的一个对象,ram为RAM类的一个对象,cdrom为CDROM类的一个对象,定义并实现这个类,为以上的类编写构造和析构函数,观察组合类和内嵌类的构造函数和析构函数的调用顺序。
5)为题目2)的类编写复制构造函数,在主函数中利用复制构造的方式创建新的对象,观察对象的状态。
6)思考并回答以下概念:函数重载,引用,类,对象,数据成员,函数成员,访问属性,构造函数,析构函数,类的组合,内嵌对象,初始化列表,复制构造函数。
三、实验主要流程、基本操作或核心代码、算法片段(该部分如不够填写,请填写至附页)
1.编写重载函数Max1可分别求取两个整数,三个整数,两个双精度数,三个双精度数的最大值。
class Max1
{
public:
Max1();
virtual ~Max1();
int MAX1(int a,int b);
int MAX1(int a,int b,int c);
double MAX1(double a,double b);
double MAX1(double a,double b,double c);
};
Max1::Max1()
{
}
Max1::~Max1()
{
}
int Max1::MAX1(int a,int b)
{
return a>b?a:b;
}
int Max1::MAX1(int a,int b,int c)
{
return a>b?(a>c?a:c):(b>c?b:c);
}
double Max1::MAX1(double a,double b)
{
return a>b?a:b;
}
double Max1::MAX1(double a,double b,double c)
{
return a>b?(a>c?a:c):(b>c?b:c);
}
#include
#include "Max1.h"
void main()
{
Max1 mymax;
cout<<mymax.MAX1(2,3)<<endl;
cout<<mymax.MAX1(2,3,4)<<endl;
cout<<mymax.MAX1(2.5,3.5)<<endl;
cout<<mymax.MAX1(2.5,3.5,4.5)<<endl;
}
2.写一个函数,具有一个引用作为形参参数,在函数中改变引用变量的值,观察实参变量的变化
#include
void change(int &a)
{
a=100;
}
void change1(int a)
{
a=100;
}
int change2(int a)
{
a=100;
return a;
}
void main()
{
int a=1;
change(a);
cout<<"引用作形参"<<a<<endl;
a=1;
change1(a);
cout<<"直接作形参"<<a<<endl;
a=1;
a=change2(a);
cout<<"直接做形参并返回"<<a<<endl;
}
3.定义一个CPU类,包含等级(Rank)、频率(frequency)、电压(voltage)等属性,有两个公有成员函数run、stop。其中,rank为枚举类型CPU__Rank,定义为enum CPU_Rank{P1=1,P2,P3,P4,P5,P6,P7},frequency为单位是MHz的整型数,voltage为浮点型的电压值。观察构造函数和析构函数的调用顺序。
enum CPU_Rank{P1=1,P2,P3,P4,P5,P6,P7};
class CPU
{
public:
CPU(enum CPU_Rank r,int f,float v);
virtual ~CPU();
void run();
void stop();
private:
enum CPU_Rank Rank;
int frequency;
float voltage;
};
CPU::CPU(enum CPU_Rank r,int f,float v)
{
Rank=r;
frequency=f;
voltage=v;
}
CPU::~CPU()
{
cout<<"析构了函数"<<endl;
}
void CPU::run(){
cout<<Rank<<" "<<frequency<<" "<<voltage<<endl;
}
void CPU::stop(){
cout<<"结束了"<<endl;
}
#include
#include "PU.h"
void main()
{
CPU mycpu(P2,777,56.5);
mycpu.run();
mycpu.stop();
mycpu.~CPU();
}
4.为题目2)的类编写复制构造函数,在主函数中利用复制构造的方式创建新的对象,观察对象的状态。
class POINT
{
public:
POINT(int xx,int yy);
int gety();
int getx();
POINT(POINT &p);
virtual ~POINT();
private:
int y;
int x;
};
POINT::POINT(int xx,int yy)
{
x=xx;
y=yy;
}
POINT::POINT(POINT &p)
{
x=p.x;
y=p.y;
cout<<"复制"<<endl;
}
#include
#include "POINT.h"
void change(int &a)
{
a=100;
}
void change1(int a)
{
a=100;
}
int change2(int a)
{
a=100;
return a;
}
void fun1(POINT p)
{
cout<<p.getx()<<endl;
}
POINT fun2()
{
POINT a(2,2);
return a;
}
void main()
{
int a=1;
change(a);
cout<<"引用作形参"<<a<<endl;
a=1;
change1(a);
cout<<"直接作形参"<<a<<endl;
a=1;
a=change2(a);
cout<<"直接做形参并返回"<<a<<endl;
POINT c(5,5);
POINT b=c;
cout<<b.getx()<<endl;
fun1(b);
b=fun2();
cout<<b.getx()<<endl;
}
5.并回答以下概念:函数重载,引用,类,对象,数据成员,函数成员,访问属性,构造函数,析构函数,类的组合,内嵌对象,初始化列表,复制构造函数。
函数重载:在C++中允许同一个函数名中的参数类型和个数不同,从而在不同的情况下使用同一函数名进行调用
引用:在函数参数中使用&符号,使传入参数即实参的值改变
类:形象上来说它类似结构体,但是它具有“方法”,内部可以对属性或者方法进行区别(public,private,protect)
数据成员:即具有不同的基本数据类型
函数成员:即方法,有构造函数,析构函数,以及其他自定义函数
访问属性:public可以被外界调用,private是私有不能被外界调用,protect是保护类型可以被子类调用
构造函数:系统在类建立的时候对类进行初始化,也可以自己进行定义
析构函数:在程序结束的时候将类释放
类的组合:在程序中可以建立多个类,在类中也可以调用另一个类,前提是要包含头文件,或者建立子类直接调用
内嵌对象:即在一个类中定义另一个类的对象
初始化列表:主要是在构造函数中进行初始化时,在参数列表后面对其中的对象进行赋初值,主要使用“:”符号进行赋值,使用“,”将不同对象赋值隔开
复制构造函数:在构造函数中使用引用,在同类对象赋值中可以调用,在函数传入对象实参,函数会自动建立复制对象形参
一、实验目的及要求
1.观察程序运行中变量的作用域、生存期和可见性;
2.学习类的静态成员的使用;
3.学习多文件结构在C++程序中的使用。
二、实验内容
CLIENT.h
class CCLIENT
{
public:
static void ShowServerName();
//使用静态函数输出ServerName
static void ShowClientNum();
//使用静态函数输出ClientNum
char GetClienName();
//返回客户机名字
int GetClientNum();
//返回客户机数量
static void ChangeServerName(char NewServerName);
//修改保存的服务器名字
CCLIENT(char ClienName);
//初始化客户机
CCLIENT(CCLIENT &CC);
//定义复制构造函数并将客户机数量++
virtual ~CCLIENT();
//定义析构函数并将客户机数量--
private:
static int ClientNum;
//记录客户机数量
static char ServerName;
//定义连接的服务器名字
char ClienName;
//定义连接的客户机名字
};
CLIENT.cpp
#include "CLIENT.h"
#include "iostream.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CCLIENT::CCLIENT(char ClienName)
{
this->ClienName=ClienName;
ClientNum++;
}
CCLIENT::CCLIENT(CCLIENT &CC)
{
ClienName=CC.ClienName;
ClientNum++;
}
CCLIENT::~CCLIENT()
{
ClientNum--;
}
void CCLIENT::ChangeServerName(char NewServerName)
{
ServerName=NewServerName;
}
int CCLIENT::GetClientNum()
{
return ClientNum;
}
char CCLIENT::GetClienName()
{
return ClienName;
}
void CCLIENT::ShowClientNum()
{
cout<<"ClientNum is "<<ClientNum<<endl;
}
void CCLIENT::ShowServerName()
{
cout<<"ServerName is "<<ServerName<<endl;
}
test.cpp
#include "CLIENT.h"
#include "stdio.h"
#include "iostream.h"
int CCLIENT::ClientNum=0;
//对ClientNum进行初始化
char CCLIENT::ServerName='a';
//对ServerName进行初始化
CCLIENT F('f');
//声明对象具有静态生存期,命名空间作用域
void main()
{
CCLIENT A('a');
CCLIENT::ShowClientNum();
//测试ClientNum是否增加
CCLIENT B=F;
cout<<"用复制构造函数赋值的B的ClienName为:"<<B.GetClienName()<<endl;
CCLIENT::ShowClientNum();
//测试赋值构造函数的功能,并且检验ClientNum是否增加
cout<<"使用类的公共函数返回ClientNum的值为:"<<A.GetClientNum()<<endl;
//使用类的函数返回ClientNum,证明ClientNum确实增加,并且是所有对象都维护的一个静态成员
if(1)
{
CCLIENT B('c');
//测试是否定义一个新的与前面同名的类,会将“远处的那个同名的类”屏蔽掉
CCLIENT::ShowClientNum();
cout<<" 具有动态生存期的是:"<<C.GetClienName()<<endl;
cout<<" 具有静态生存期的是:"<<F.GetClienName()<<endl;
}
CCLIENT::ShowClientNum();
cout<<" 具有静态生存期的是:"<<F.GetClienName()<<endl;
//测试ClientNum是否减少并且运用测试生存期
CCLIENT::ShowServerName();
CCLIENT::ChangeServerName('g');
CCLIENT::ShowServerName();
//测试通过ChangeServerName函数修改ServerName
}
四、实验结果的分析与评价(该部分如不够填写,请填写至附页)
类的静态数据成员:在数据成员前加上static即成为静态数据成员,它由所有同类的对象维护,可以通过静态函数成员进行修改,也可以通过静态函数成员调用。在使用前需要进行初始化,可以在主函数外进行,初始化的方法是类型加上类名再通过“::”直接进行赋值
类的静态函数成员:在函数成员前加static即成为静态函数成员,静态函数成员只能调用静态数据成员,静态函数成员可以不通过对象名直接通类名调用
多文件结构:就是模块化程序设计,或者说将代码分步书写,将每个类的定义写入一个头文件,将对应类的方法的实现又写入一个cpp中,最后在主程序中直接调用即可
文件包含:指在一个源文件中,通过文件包含命令将另一个源文件的内容全部包含在此文件中。在源文件编译时,连同被包含进来的文件一同编译,生成目标目标文件
一、实验目的及要求
1)学习使用数组;学习字符串数据的组织和处理;学习标准C++库的使用;
2)掌握指针的使用方法;练习通过debug观察指针的内容及其所指的对象的内容;练习通过动态内存分配实现动态数组,并体会指针在其中的作用;
3)分别使用字符数组和标准C++库练习处理字符串的方法。
二、实验内容
1)编写一个类用于处理3×3矩阵转置,测试转置的效果,输出转置前后的矩阵。
2)定义一个具有构造函数和析构函数的类,如实验一的CPU类,定义一个CPU的对象数组,观察构造函数的析构函数的调用过程。
3)利用动态内存分配的方式重新完成题目2)。
4)使用系统提供的string类定义字符串对象并初始化,实现从原始字符串中提取一个子串。
5)选做:定义一个Point(二维点类)的对象数组,利用该数组实现直线的线性拟合。
6)选做:定义一个动态数组类。
7)思考并回答:数组,指针,对象数组,动态内存分配,默认构造函数,标准类库,字符串类 string,线性拟合。
三、实验主要流程、基本操作或核心代码、算法片段(该部分如不够填写,请填写至附页)
//1)编写一个类用于处理3×3矩阵转置,测试转置的效果,输出转置前后的矩阵
class Three_Three
{
public:
Three_Three();
Three_Three(int H,int L,int *p)
{
Hang=H;
Lie=L;
pr=p;
}
void Zhuan_Zhi();
virtual ~Three_Three();
private:
int Hang;
int Lie;
int *pr;
};
Three_Three::Three_Three()
{
}
Three_Three::~Three_Three()
{
}
void Three_Three::Zhuan_Zhi()
{
int i=0,j=0;
printf("转置前:\n");
for(i=0;i<Hang;i++)
{
for(j=0;j<Lie;j++)
printf("%d\t",*(pr+i*Lie)+j);
printf("\n");
}
printf("转置后:\n");
for(i=Lie-1;i>=0;i--)
{
for(j=0;j<Hang;j++)
printf("%d\t",*(pr+j*Lie)+i);
printf("\n");
}
}
//2)定义一个具有构造函数和析构函数的类,如实验一的CPU类,定义一个CPU的对象数组,观察构造函数的析构函数的调用过程。
enum CPU_Rank{P1=1,P2,P3,P4,P5,P6,P7};
class CPU
{
public:
CPU();
CPU(enum CPU_Rank r,int f,float v);
CPU(CPU &c);
virtual ~CPU();
void run();
void stop();
private:
enum CPU_Rank Rank;
int frequency;
float voltage;
};
CPU::CPU()
{
cout<<"构建了CPU类的一个对象"<<endl;
}
CPU::CPU(CPU &c)
{
Rank=c.Rank;
frequency=c.frequency;
voltage=c.voltage;
cout<<"构建了CPU类的一个对象"<<endl;
}
CPU::CPU(enum CPU_Rank r,int f,float v)
{
Rank=r;
frequency=f;
voltage=v;
cout<<"构建了CPU类的一个对象"<<endl;
}
CPU::~CPU()
{
cout<<"析构了CPU类的一个对象"<<endl;
}
void CPU::run()
{
cout<<Rank<<" "<<frequency<<" "<<voltage<<endl;
}
void CPU::stop()
{
cout<<"CPU停止"<<endl;
}
class Point
{
public:
void Change_Value(int x,int y);
Point(int x=0,int y=0);
Point(Point &P)
{
x=P.x;
y=P.y;
}
virtual ~Point();
friend float Squre_sum(Point c[N]);
friend float Sum_Average_X(Point d[N]);
friend float Sum_Average_Y(Point d[N]);
friend float Mul(Point m[N]);
friend void Line_Fit(Point p[N]);
friend class arrayofpoint;
private:
int x;
int y;
};
Point::Point(int x,int y):x(x),y(y)
{
}
Point::~Point()
{
}
float Squre_sum(Point c[N])
{
unsigned int i=0;
float z=0;
for(i=0;i<N;i++)
{
z = z + c[i].x*c[i].x;
}
return z;
}
float Sum_Average_X(Point d[N])
{
unsigned int i=0;
float z=0;
for(i=0;i<N;i++)
{
z = z + d[i].x;
}
z = z/N;
return z;
}
float Sum_Average_Y(Point d[N])
{
unsigned int i=0;
float z=0;
for(i=0;i<N;i++)
{
z = z + d[i].y;
}
z = z/N;
return z;
}
float Mul(Point m[N])
{
unsigned int i=0;
float z=0;
for(i=0;i<N;i++)
{
z = z + m[i].x*m[i].y;
}
return z;
}
void Line_Fit(Point p[N])
{
float K=0;
//拟合直线的斜率
float R=0;
//拟合直线的截距
float x_sum_average=0;
//数组 p[N] 个点的X求和 并求平均值
float y_sum_average=0;
//数组 p[N] 个点的y求和 并求平均值
float x_square_sum=0;
//数组 p[N] 个点的X的平方求和
float x_multiply_y=0;
//数组 p[N] 个点的X和Y对应的乘积
x_sum_average= Sum_Average_X(p);
y_sum_average= Sum_Average_Y(p);
x_square_sum = Squre_sum(p);
x_multiply_y = Mul(p);
K = ( x_multiply_y - N * x_sum_average * y_sum_average)/( x_square_sum - N * x_sum_average*x_sum_average );
R = y_sum_average - K * x_sum_average;
printf("K = %f\n",K);
printf("R = %f\n",R);
}
void Point::Change_Value(int x, int y)
{
this->x=x;
this->y=y;
}
class arrayofpoint
{
public:
arrayofpoint(int size)
{
sizee=size;
points=new Point[size];
cout<<"创建了"<<size<<"个Point类对象"<<endl;
}
~arrayofpoint()
{
cout<<"deleting..."<<endl;
delete[] points;
}
//获得下标为index的数组元素
Point element(int index)
{
assert(index>=0&&index<sizee);
//如果数组下标越界,程序中止
return points[index];
}
private:
Point *points;
int sizee;
};
#include "stdio.h"
#include "iostream.h"
#include
using namespace std;
#include "Three_Three.h"
#include "PU.h"
#include "Point.h"
#include "arrayofpoint.h"
#define N 10
void main()
{
{
int a[3][3]={{1,2,3},{4,5,6},{7,8,9}};
Three_Three T(3,3,(int*)a);
T.Zhuan_Zhi();
}
//1)编写一个类用于处理3×3矩阵转置,测试转置的效果,输出转置前后的矩阵。
{
CPU mycpu(P2,777,56.5);
cout<<"CPU的对象数组:"<<endl;
{
CPU c[4];
int i=0;
for(i=0;i<4;i++)
{
c[i]=mycpu;
}
}
cout<<"动态内存分配:"<<endl;
{
CPU *cc=new CPU;
delete cc;
}
cout<<"最后析构的对象是最初创建的那个对象:"<<endl;
}
//2)定义一个具有构造函数和析构函数的类,如实验一的CPU类,定义一个CPU的对象数组,观察构造函数的析构函数的调用过程。
{
string s="hello world! hello C++!";
cout<<"原字符串为:hello world! hello C++!"<<endl;
int i;
cout<<"现字符子串为:";
for(i=13;i<=s.size();i++)
cout<<s[i];
cout<<endl;
}
//4)使用系统提供的string类定义字符串对象并初始化,实现从原始字符串中提取一个子串。
{
/*
Point p[N];
int i;
for(i=0;i//测试用例
Point p[N]={Point(6,10),Point(14,20),Point(26,30),Point(33,40),Point(46,50),Point(54,60),Point(67,70),Point(75,80),Point(84,90),Point(100,100)};
Line_Fit(p);
}
//5)选做:定义一个Point(二维点类)的对象数组,利用该数组实现直线的线性拟合。
{
int countt;
cout<<"请输入需要创建的点的个数:";
cin>>countt;
arrayofpoint points(countt);//创建对象数组
points.element(0).Change_Value(1,1);
}
//6)选做:定义一个动态数组类。
}
四、实验结果的分析与评价(该部分如不够填写,请填写至附页)
数组:相同类型元素的集合
指针:指向地址的一种数据类型,保存的是地址值,可以通过指针对指向地址的存储空间进行操作
对象数组:数组的元素由相同类的不同对象组成,进行初始化的时候以这种方式赋值:
Ponit a[3]={Ponit(1,1),Ponit(2,2,),Ponit3,3)};
动态内存分配:通过new动态创建指定类型数据,再通过delete进行销毁,在动态申请对象数组时, 不确定数组元素的个数,可以通过new进行创建,但是只能以delete销毁
默认构造函数:对于类而言就是系统自动为其创建的函数
标准类库:这个概念不是很清楚,是“use namespace std”
字符串类 string:这个是C++为方便开发者而提供的一种类,通过这个类可以很方便的为字符串进行赋值,求长度等操作,但是需要加上#include
线性拟合:书上对象数组章节有提到,但老师未讲过,我信息检索了一下,其实就是通过一些点,得到一条线,让那些点尽可能的在那条线周围,于是通过百度到线性拟合的公式,求出了书上例子里的直线的K和R
一、实验目的及要求
二、实验内容
1)定义一个基类Animal,有私有整型成员变量age,构造其派生类dog,在其成员函数SetAge(int n)中直接给age赋值,看看会有什么问题,把 age改为公有成员变量,还会有问题吗?编程试试看。
2)定义一个基类BaseClass,有整型成员变量Number,构造其派生类DerivedClass,定义该派生类的对象,观察构造函数和析构函数的执行情况。
3)定义一个车(vehicle)基类,具有MaxSpeed、Weight等成员变量,Run、Stop等成员函数,由此派生出自行车(bicycle)类,汽车(motorcycle)类。自行车(bicycle)类有高度(Height)等属性,汽车(motorcycle)类有座位数(SeatNum)等属性。从bicycle和motorcycle派生出摩托车(Motorcar)类,在继承过程中,注意把vehicle设置为虚基类。如果不把vehicle 设置为虚基类,会有什么问?编程实验及分析原因。
4)思考并回答:继承,派生,子类对基类成员的访问权限,继承方式,继承时的构造函数和析构函数的调用顺序,虚基类
三、实验主要流程、基本操作或核心代码、算法片段(该部分如不够填写,请填写至附页)
第一题:
class Animal
{
public:
Animal();
virtual ~Animal();
int age;
private:
};
class dog : public Animal
{
public:
void SetAge(int n);
dog();
virtual ~dog();
};
void dog::SetAge(int n)
{
age=n;
}
第二题:
class BaseClass
{
public:
int Number;
BaseClass();
virtual ~BaseClass();
};
BaseClass::BaseClass()
{
cout<<"构造了一个BaseClass类"<<endl;
}
BaseClass::~BaseClass()
{
cout<<"析构了一个BaseClass类"<<endl;
}
class DerivedClass : public BaseClass
{
public:
DerivedClass();
virtual ~DerivedClass();
};
DerivedClass::DerivedClass()
{
cout<<"构造了一个DerivedClass类"<<endl;
}
DerivedClass::~DerivedClass()
{
cout<<"析构了一个DerivedClass类"<<endl;
}
第三题:
#include "iostream.h"
class vehicle
{
public:
void Stop();
void Run();
vehicle();
vehicle(vehicle &v);
vehicle(float m,float w);
virtual ~vehicle();
private:
float MaxSpeed;
float Weight;
};
vehicle::vehicle()
{
MaxSpeed=0;
Weight=0;
cout<<"创建一个vehicle空对象"<<endl;
}
vehicle::vehicle(vehicle &v)
{
MaxSpeed=v.MaxSpeed;
Weight=v.Weight;
cout<<"复制构造一个vehicle对象"<<endl;
}
vehicle::vehicle(float m,float w)
{
MaxSpeed=m;
Weight=w;
cout<<"构建一个vehicle对象"<<endl;
}
vehicle::~vehicle()
{
cout<<"析构一个vehicle对象"<<endl;
}
void vehicle::Run()
{
cout<<"运行一个vehicle"<<endl;
}
void vehicle::Stop()
{
cout<<"停止一个vehicle"<<endl;
}
class bicycle : public virtual vehicle
{
public:
void Stop();
void Run();
bicycle();
bicycle(bicycle &b):vehicle(b),Height(b.Height)
{
cout<<"复制构造一个bicycle对象"<<endl;
}
bicycle(float m,float w,float h):vehicle(m,w),Height(h)
{
cout<<"构建一个bicycle对象"<<endl;
}
virtual ~bicycle();
private:
float Height;
};
bicycle::bicycle()
{
Height=0;
cout<<"创建一个bicycle空对象"<<endl;
}
bicycle::~bicycle()
{
cout<<"析构一个bicycle对象"<<endl;
}
void bicycle::Run()
{
cout<<"运行一个bicycle"<<endl;
}
void bicycle::Stop()
{
cout<<"停止一个bicycle"<<endl;
}
class motorcycle : virtual public vehicle
{
public:
void Stop();
void Run();
motorcycle();
motorcycle(motorcycle &m):vehicle(m),SeatNum(m.SeatNum)
{
cout<<"复制构造一个motorcycle对象"<<endl;
}
motorcycle(float m,float w,int s):vehicle(m,w),SeatNum(s)
{
cout<<"构建一个motorcycle对象"<<endl;
}
virtual ~motorcycle();
private:
int SeatNum;
};
motorcycle::motorcycle()
{
SeatNum=0;
cout<<"创建一个motorcycle空对象"<<endl;
}
motorcycle::~motorcycle()
{
cout<<"析构一个motorcycle对象"<<endl;
}
void motorcycle::Run()
{
cout<<"运行一个motorcycle"<<endl;
}
void motorcycle::Stop()
{
cout<<"停止一个motorcycle"<<endl;
}
class Motorcar :
public bicycle,
public motorcycle
{
public:
void Stop();
void Run();
Motorcar();
Motorcar(Motorcar &m):vehicle(m),bicycle(m),motorcycle(m)
{
cout<<"复制构造一个Motorcar对象"<<endl;
}
Motorcar(float m,float w,float h,int s):vehicle(m,w),bicycle(m,w,h),motorcycle(m,w,s)
{
cout<<"构建一个Motorcar对象"<<endl;
}
virtual ~Motorcar();
};
Motorcar::Motorcar()
{
cout<<"创建一个Motorcar空对象"<<endl;
}
Motorcar::~Motorcar()
{
cout<<"析构一个Motorcar对象"<<endl;
}
void Motorcar::Run()
{
cout<<"运行一个Motorcar"<<endl;
}
void Motorcar::Stop()
{
cout<<"停止一个Motorcar"<<endl;
}
void fun(vehicle *p)
{
p->Run();
p->Stop();
}
int main()
{
Motorcar m1;//调用默认构造函数
Motorcar m2(1,2,3,4);//调用带参数的构造函数
Motorcar m3=m2;//调用复制构造函数
//以下是使用三种方式调用基类的函数
{
m1.vehicle::Run();
m1.vehicle::Stop();
}
vehicle *pv=&m1;
pv->Run();
pv->Stop();//使用vehicle的函数
fun(pv);
{
m2.motorcycle::Run();
m2.motorcycle::Stop();
}
motorcycle *pm=&m2;
pm->Run();
pm->Stop();//使用motorcycle的函数
fun(pm);
{
m3.bicycle::Run();
m3.bicycle::Stop();
}
bicycle *pb=&m3;
pb->Run();
pb->Stop();//使用bicycle的函数
fun(pb);
return 0;
}
第四题:
继承:指新的类从已有的类那里得到已有的特性,节约开发人员的时间,提高效率
派生:首先只有一个基类的派生也叫单继承,派生可以具有多个基类
子类对基类成员的访问权限:可以访问基类的公有成员
继承方式:有三种:public,private,protect。其中public最常用
继承时的构造函数和析构函数的调用顺序:构造时先构造最“原始的”基类,再跟着派生的顺序进行构造,析构的顺序和构造相反
虚基类:将共同的基类设为虚基类,避免构造的时候产生矛盾,对同一个类进行多次构造
一、实验目的及要求
掌握运算符重载的方法;学习使用虚函数实现动态多态性。
二、实验内容
1)定义Point类,有坐标x,y两个私有成员变量;对Point类重载“+”(相加)、“-”(相减)和“==”(相等)运算符,实现对坐标的改变,要求用友元函数和成员函数两种方法实现。对Point类重载<<运算符,以使得代码 Point p; cout<
2)定义一个车(vehicle)基类,有虚函数Run、Stop等成员函数,由此派生出自行车(bicycle)类、汽车(motorcar)类,它们都有Run、Stop等成员函数。在主函数中用不同的方法调用Run、Stop成员函数,观察这些函数的执行结果,思考如何实现动态多态性,如果Run、Stop没有被定义为虚函数,执行结果会怎样,把结果和分析写入实验报告。
3)选做,利用类完成求函数的积分(参考教材)。
4)思考并回答:多态,实现多态性的方法,虚函数,运算符重载,前++,后++,实现运算符重载的方式。
三、实验主要流程、基本操作或核心代码、算法片段(该部分如不够填写,请填写至附页)
第一题:
#include "iostream.h"
class Point
{
public:
Point(int x=0,int y=0)
{
this->x=x;
this->y=y;
}
virtual ~Point();
// Point operator +(const Point &p);
// Point operator -(const Point &p);
// bool operator ==(const Point &p);
Point &operator ++();//前置单目运算符
Point operator ++(int);//后置单目运算符
friend Point operator +(const Point &p1,const Point &p2);
friend Point operator -(const Point &p1,const Point &p2);
friend bool operator ==(const Point &p1,const Point &p2);
friend ostream & operator <<(ostream &out,const Point &p);
private:
int y;
int x;
};
Point::~Point()
{
}
/*
Point Point::operator +(const Point &p)
{
return Point(p.x+x,p.y+y);
}
Point Point::operator -(const Point &p)
{
return Point(x-p.x,y-p.y);
}
bool Point::operator ==(const Point &p)
{
if(x==p.x&&y==p.y)
return true;
else
return false;
}
*/
Point &Point::operator ++()//前置单目运算符
{
x++;
y++;
return *this;
}
Point Point::operator ++(int)//后置单目运算符
{
Point old = *this;
++(*this);
return old;
}
Point operator +(const Point &p1,const Point &p2)
{
return Point(p1.x+p2.x,p1.y+p2.y);
}
Point operator -(const Point &p1,const Point &p2)
{
return Point(p1.x-p2.x,p1.y-p2.y);
}
bool operator ==(const Point &p1,const Point &p2)
{
if(p1.x==p2.x&&p1.y==p2.y)
return true;
else
return false;
}
ostream & operator <<(ostream &out,const Point &p)
{
out<<"("<<p.x<<","<<p.y<<")";
return out;
}
int main(int argc, char* argv[])
{
Point a(1,1),b(2,2);
Point c;
c=a+b;
cout<<c<<endl;
cout<<"a++="<<a++<<endl;
cout<<"++a="<<++a<<endl;
if(a==b)
cout<<a<<"=="<<b<<endl;
else
cout<<a<<"!="<<b<<endl;
return 0;
}
第二题:
#include"iostream.h"
class vehicle
{
public:
virtual void Stop();
virtual void Run();
vehicle();
virtual ~vehicle();
};
void vehicle::Run()
{
cout<<"Run vehicle"<<endl;
}
void vehicle::Stop()
{
cout<<"Stop vehicle"<<endl;
}
#include "vehicle.h"
class motorcar : virtual public vehicle
{
public:
virtual void Stop();
virtual void Run();
motorcar();
virtual ~motorcar();
};
void motorcar::Run()
{
cout<<"Run motorcar"<<endl;
}
void motorcar::Stop()
{
cout<<"Stop motorcar"<<endl;
}
#include "vehicle.h"
class bicycle : virtual public vehicle
{
public:
virtual void Stop();
virtual void Run();
bicycle();
virtual ~bicycle();
};
void bicycle::Run()
{
cout<<"Run bicycle"<<endl;
}
void bicycle::Stop()
{
cout<<"Stop bicycle"<<endl;
}
int main(int argc, char* argv[])
{
vehicle v;
bicycle b;
motorcar m;
v.Run();
b.Run();
m.Run();
vehicle *p;
p=&v;
p->Stop();
p=&b;
p->Stop();
p=&m;
p->Stop();
return 0;
}
一、实验目的及要求
1)理解模板的作用和语法。
2)学习掌握C++文件处理类的基本用法。
二、实验内容
1)使用函数模板实现一个求3个数最大值的函数,并完成测试。
2)编写程序,用文本方式打开指定的一个文件,在每一行前加行号。
3)选做,练习使用STL中的vector模板类。
4)选做,定义一个异常类CException,有成员函数Reason(),用来显示异常的类型。在子函数中触发异常,在主程序中处理异常,观察程序的执行过程。
5)思考并回答:模板,函数模板,类模板,文件,文件读写,文件流类,文件操作方式,文件存储方式; STL,容器,异常处理。
三、实验主要流程、基本操作或核心代码、算法片段(该部分如不够填写,请填写至附页)
第一题:
#include"iostream"
using namespace std;
template<typename T>
T GetMaxFromThree(T a,T b,T c)
{
return a>b?(a>c?a:c):(b>c?b:c);
}
void main()
{
int a,b,c;
cin>>a>>b>>c;
cout<<GetMaxFromThree(a,b,c)<<endl;
}
第二题
#include
#include
#include
using namespace std;
void main()
{
string line;//定义字符串变量存储每行字符串
int linenum=1;//定义行标
ifstream a("e://123.txt");
ofstream b("e://111.txt");
while(!a.eof ())
{
if(getline(a,line))//如果取出的字符串不为空,则写入另一个文件中
b<<linenum++<<":"<<line<<endl;
}
a.close ();
b.close ();
}
第三题:
#include
#include
using namespace std;
template <typename T>
void Showelements(vector <T>vec, int n);
void main()
{
//虽然可以对给定元素个数的 vector 对象预先分配内存,
//但更有效的方法是先初始化一个空 vector 对象,
//然后再动态地增加元素
//定义,且长度为 0 的空vector对象
vector <int> vt1;
//定义,初始化每一个元素为0
vector <int> vt2(10);
Showelements(vt2, 10);
//定义,初始化每一个元素为单字符 ‘*’
vector <char> vt3(10, '*');
Showelements(vt3, 10);
//定义,深拷贝初始化
vector <int> vt5(vt2);
Showelements(vt5, 10);
}
template <typename T>
void Showelements(vector <T> vec, int n)
{
cout << "-----------------------" << endl;
int i = 0;
for (i = 0; i < n; i++)
{
cout << "\t#" << i << ": " << vec[i] << endl;
}
return;
}
第四题
#include
#include
using namespace std;
class MyException
{
public:
MyException(const string &message):message(message){}
~MyException(){}
const string &getMessage() const { return message; }
private:
string message;
};
class Demo
{
public:
Demo(){cout<<"Constructor of Demo"<<endl;}
~Demo(){cout<<"Destructor of Demo"<<endl;}
};
void func() throw(MyException)
{
Demo d;
cout<<"Throw MyException in func()"<<endl;
throw MyException("exception throw by func()");
}
int divide(int x,int y)
{
if(y==0)
throw x;
return x/y;
}
int main()
{
//--------------------------------------//
try
{
cout<<"5/2="<<divide(5,2)<<endl;
cout<<"8/0="<<divide(8,0)<<endl;
cout<<"7/1="<<divide(7,1)<<endl;
}
catch(int e)
{
cout<<e<<" is divided by zero!"<<endl;
}
cout<<"That is ok."<<endl;
//--------------------------------------//
cout<<"In main function"<<endl;
try
{
func();
}
catch(MyException &e)
{
cout<<"Caught an exception:"<<e.getMessage ()<<endl;
}
cout<<"Resume the execution of main()"<<endl;
return 0;
}