C++实验代码

类与对象

一、实验目的及要求
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是保护类型可以被子类调用
构造函数:系统在类建立的时候对类进行初始化,也可以自己进行定义
析构函数:在程序结束的时候将类释放
类的组合:在程序中可以建立多个类,在类中也可以调用另一个类,前提是要包含头文件,或者建立子类直接调用
内嵌对象:即在一个类中定义另一个类的对象
初始化列表:主要是在构造函数中进行初始化时,在参数列表后面对其中的对象进行赋初值,主要使用“:”符号进行赋值,使用“,”将不同对象赋值隔开
复制构造函数:在构造函数中使用引用,在同类对象赋值中可以调用,在函数传入对象实参,函数会自动建立复制对象形参


C++程序的结构

一、实验目的及要求
1.观察程序运行中变量的作用域、生存期和可见性;
2.学习类的静态成员的使用;
3.学习多文件结构在C++程序中的使用。
二、实验内容

  1. 实现客户机(CLIENT)类。定义字符型静态数据成员ServerName,保存其服务器名称;整型静态数据成员ClientNum,记录已定义的客户数量;定义静态函数ChangeServerName()改变服务器名称。
  2. 利用多文件结构实现题目1),在头文件client.h中定义类,在文件client.cpp中实现该类,在文件test.cpp 中测试这个类,观察相应的成员变量取值的变化情况,要求ClientNum能够实时记录客户机对象的数量。
  3. 思考并回答以下概念: 类的静态数据成员,类的静态函数成员,多文件结构,文件包含。
    三、实验主要流程、基本操作或核心代码、算法片段(该部分如不够填写,请填写至附页)
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. 学习定义和使用类的继承关系,定义派生类;熟悉不同继承方式下对基类成员的访问控制;
  2. 学习利用虚基类解决二义性问题。

二、实验内容
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;
}

你可能感兴趣的:(C++,C++)