实验五 构造函数和析构函数
A. Point(类与构造)
题目描述
下面是一个平面上的点的类定义,请在类外实现它的所有方法,并生成点测试它。
输入
测试数据的组数 t
第一组测试数据点p1的x坐标 第一组测试数据点p1的y坐标 第一组测试数据点p2的x坐标 第一组测试数据点p2的y坐标
…
输出
输出p1到p2的距离
在C++中,输出指定精度的参考代码如下:
#include
#include //必须包含这个头文件
using namespace std;
void main( )
{ double a =3.141596;
cout<<fixed<<setprecision(3)<<a<<endl; //输出小数点后3位
}
输入样例
2
1 2 3 4
-1 0.5 -2 5
输出样例
Distance of Point(1.00,2.00) to Point(3.00,4.00) is 2.83
Distance of Point(-1.00,0.50) to Point(-2.00,5.00) is 4.61
参考代码
#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;
class Point
{
double x,y;
public:
Point();//缺省构造函数
Point(double x_value,double y_value);//有参构造函数
double getX();//返回x的值
double getY();//返回y的值
void setX(double x_value);
void setY(double y_value);
double distanceToAnotherPoint(Point p);
};
Point::Point()
{
x=0;
y=0;
}
Point::Point(double x_value,double y_value)
{
x=x_value;
y=y_value;
}
void Point::setX(double x_value)
{
x=x_value;
}
void Point::setY(double y_value)
{
y=y_value;
}
double Point::getX()
{
return x;
}
double Point::getY()
{
return y;
}
double Point::distanceToAnotherPoint(Point p)
{
double len_x;
double len_y;
double len;
len_x=x-p.x;
len_y=y-p.y;
len=sqrt(len_x*len_x+len_y*len_y);
return len;
}
int main()
{
int t;//测试组数
Point p1,p2;
double x1,y1,x2,y2,dis;
cin>>t;
while(t--)
{
cin>>x1>>y1>>x2>>y2;
//设置两个点的坐标
p1.setX(x1);
p1.setY(y1);
p2.setX(x2);
p2.setY(y2);
dis=p1.distanceToAnotherPoint(p2);
cout<<"Distance of Point("<<fixed<<setprecision(2)<<p1.getX()<<','<<fixed<<setprecision(2)<<p1.getY()<<')';
cout<<" to Point("<<fixed<<setprecision(2)<<p2.getX()<<','<<fixed<<setprecision(2)<<p2.getY()<<')';
cout<<" is "<<fixed<<setprecision(2)<<dis<<endl;
}
}
B. Date(类与构造)
题目描述
下面是一个日期类的定义,请在类外实现其所有的方法,并在主函数中生成对象测试之。
注意,在判断明天日期时,要加入跨月、跨年、闰年的判断
例如9.月30日的明天是10月1日,12月31日的明天是第二年的1月1日
2月28日的明天要区分是否闰年,闰年则是2月29日,非闰年则是3月1日
输入
测试数据的组数t
第一组测试数据的年 月 日
…
要求第一个日期的年月日初始化采用构造函数,第二个日期的年月日初始化采用setDate方法,第三个日期又采用构造函数,第四个日期又采用setDate方法,以此类推。
输出
输出今天的日期
输出明天的日期
输入样例
4
2012 1 3
2012 2 28
2012 3 31
2012 4 30
输出样例
Today is 2012/01/03
Tomorrow is 2012/01/04
Today is 2012/02/28
Tomorrow is 2012/02/29
Today is 2012/03/31
Tomorrow is 2012/04/01
Today is 2012/04/30
Tomorrow is 2012/05/01
参考代码
#include<iostream>
#include<iomanip>
using namespace std;
class Date
{
int year,month,day;
public:
Date();//缺省构造函数
Date(int y,int m,int d);
int getYear();
int getMonth();
int getDay();
void setDate(int y,int m,int d);
void print();
void addOneDay();
};
Date::Date()
{
year=1900,month=1,day=1;
}
Date::Date(int y,int m,int d)
{
year=y;
month=m;
day=d;
}
int Date::getDay()
{
return day;
}
int Date::getMonth()
{
return month;
}
int Date::getYear()
{
return year;
}
void Date::setDate(int y,int m,int d)
{
year=y;
month=m;
day=d;
}
void Date::print()
{
cout<<setfill('0')<<setw(4)<<year<<'/'<<setw(2)<<month<<'/'<<setw(2)<<day<<endl;
}
void Date::addOneDay()
{
//把每月的天数放入数组中
int mon[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int Leap;
if(year%4==0&&year%100!=0||year%400==0) Leap=1;
else Leap=0;
if(Leap) mon[2]=29;
day++;
if(day>mon[month])
{
month++;
day=1;
}
if(month>12)
{
year++;
month=1;
}
}
int main()
{
int t,ye,mo,da;
cin>>t;
Date p1;
while(t--)
{
cin>>ye>>mo>>da;
p1.setDate(ye,mo,da);
cout<<"Today is ";
p1.print() ;
p1.addOneDay();
cout<<"Tomorrow is ";
p1.print() ;
}
}
C. 分数类(类与构造)
题目描述
完成下列分数类的实现:
class CFraction
{
private:
int fz, fm;
public:
CFraction(int fz_val, int fm_val) ;
CFraction add(const CFraction &r);
CFraction sub(const CFraction &r);
CFraction mul(const CFraction &r);
CFraction div(const CFraction &r);
int getGCD(); // 求对象的分子和分母的最大公约数
void print();
};
求两数a、b的最大公约数可采用辗转相除法,又称欧几里得算法,其步骤为:
- 交换a, b使a > b;
- 用a除b得到余数r,若r=0,则b为最大公约数,退出.
- 若r不为0,则用b代替a, r代替b,此时a,b都比上一次的小,问题规模缩小了;
- 继续第2步。
输入
测试数据的组数 t
第一组第一个分数
第一组第二个分数
第二组第一个分数
第二组第二个分数
…
输出
第一组两个分数的和
第一组两个分数的差
第一组两个分数的积
第一组两个分数的商
第二组两个分数的和
第二组两个分数的差
第二组两个分数的积
第二组两个分数的商
…
输入样例
3
1/2
2/3
3/4
5/8
21/23
8/13
输出样例
7/6
-1/6
1/3
3/4
11/8
1/8
15/32
6/5
457/299
89/299
168/299
273/184
参考代码
#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;
class CFraction
{
int fz, fm;//分子分母
public:
CFraction(int fz_val, int fm_val) ;
CFraction add(const CFraction &r);//加
CFraction sub(const CFraction &r);//减
CFraction mul(const CFraction &r);//乘
CFraction div(const CFraction &r);//除
int getGCD(); // 求对象的分子和分母的最大公约数
void print();
CFraction(){};
};
CFraction::CFraction(int fz_val, int fm_val)
{
fz=fz_val;
fm=fm_val;
}
CFraction CFraction::add(const CFraction &r)
{
CFraction temp(fz*r.fm+r.fz *fm,fm*r.fm);
int gcd=temp.getGCD();
temp.fz=temp.fz/gcd;
temp.fm=temp.fm/gcd;
return temp;
}
CFraction CFraction::sub(const CFraction &r)
{
CFraction temp((fz*r.fm-r.fz *fm),fm*r.fm);
int gcd=temp.getGCD();
temp.fz=temp.fz/gcd;
temp.fm=temp.fm/gcd;
return temp;
}
CFraction CFraction::mul(const CFraction &r)
{
CFraction temp(fz*r.fz,fm*r.fm);
int gcd=temp.getGCD();
temp.fz=temp.fz/gcd;
temp.fm=temp.fm/gcd;
return temp;
}
CFraction CFraction::div(const CFraction &r)
{
CFraction temp(fz*r.fm,r.fz *fm);
int gcd=temp.getGCD();
temp.fz=temp.fz/gcd;
temp.fm=temp.fm/gcd;
return temp;
}
int CFraction::getGCD()
{
int r;
int a,b;
if(fabs(fz)>fabs(fm))
{
a=fabs(fz);
b=fabs(fm);
}
else
{
a=fabs(fm);
b=fabs(fz);
}
while(a%b!=0)//利用辗转相除法求最大公约数
{
r=a%b;
a=b;
b=r;
}
return b;
}
void CFraction::print()
{
//如果有负数,注意把负号放前面
if(fz<0&&fm>0||fz>0&&fm<0) cout<<'-';
cout<<fabs(fz)<<'/'<<fabs(fm)<<endl;
}
int main()
{
int t;
cin>>t;
int fz1,fm1,fz2,fm2;
CFraction p3;
while(t--)
{
char ch;
cin>>fz1>>ch>>fm1>>fz2>>ch>>fm2;
CFraction p1(fz1,fm1);
CFraction p2(fz2,fm2);
p3=p1.add(p2);//进行加法运算
p3.print();
p3=p1.sub(p2); //减法
p3.print();
p3=p1.mul(p2);//乘法
p3.print();
p3=p1.div(p2);//除法
p3.print();
cout<<endl;
}
}
D. Point_Array(类+构造+对象数
题目描述
上面是我们曾经练习过的一个习题,请在原来代码的基础上作以下修改:1、增加自写的析构函数;2、将getDisTo方法的参数修改为getDisTo(const Point &p);3、根据下面输出的内容修改相应的构造函数。
然后在主函数中根据用户输入的数目建立Point数组,求出数组内距离最大的两个点之间的距离值。
输入
测试数据的组数 t
第一组点的个数
第一个点的 x 坐标 y坐标
第二个点的 x坐标 y坐标
…
输出
输出第一组距离最大的两个点以及其距离
…
在C++中,输出指定精度的参考代码如下:
#include
#include //必须包含这个头文件
using namespace std;
void main( )
{ double a =3.141596;
cout<<fixed<<setprecision(3)<<a<<endl; //输出小数点后3位
输入样例
2
4
0 0
5 0
5 5
2 10
3
-1 -8
0 9
5 0
输出样例
Constructor.
Constructor.
Constructor.
Constructor.
The longeset distance is 10.44,between p[1] and p[3].
Distructor.
Distructor.
Distructor.
Distructor.
Constructor.
Constructor.
Constructor.
The longeset distance is 17.03,between p[0] and p[1].
Distructor.
Distructor.
Distructor.
参考代码
#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;
class Point
{
double x,y;
public:
Point();//缺省构造函数
~Point()
{
cout<<"Distructor."<<endl;
}
Point(double x_value,double y_value);//有参构造函数
double getX();//返回x的值
double getY();//返回y的值
void setXY(double x1,double y1)//设置数组里的x,y
{
x=x1;
y=y1;
}
void setX(double x_value);
void setY(double y_value);
double getDisTo(const Point &p);
};
Point::Point()
{
cout<<"Constructor."<<endl;
x=0;
y=0;
}
Point::Point(double x_value,double y_value)//有参构造函数
{
x=x_value;
y=y_value;
}
double Point::getX()//返回x的值
{
return x;
}
double Point::getY()//返回y的值
{
return y;
}
void Point::setX(double x_value)//设置x
{
x=x_value;
}
void Point::setY(double y_value)//设置y
{
y=y_value;
}
double Point::getDisTo(const Point &p)
{
double len_x;
double len_y;
double len;
len_x=x-p.x;
len_y=y-p.y;
len=sqrt(len_x*len_x+len_y*len_y);
return len;
}
int main()
{
int t;//测试组数
int n;//点的个数
double x,y,dis;
cin>>t;
while(t--)
{
cin>>n;
Point *p=new Point[n];
for(int i=0;i<n;i++)
{
cin>>x>>y;
p[i].setXY(x,y);
}
double max=-99999;
int tag1,tag2;
for(int i=0;i<n-1;i++)
{
for(int j=i+1;j<n;j++)
{
if(p[i].getDisTo(p[j])>max)
{
max=p[i].getDisTo(p[j]);
tag1=i;
tag2=j;//记录最大值是哪两点产生
}
}
}
if(tag1>tag2)
{
int tem;
tem=tag1;
tag1=tag2;
tag2=tem;
}
cout<<"The longeset distance is "<<fixed<<setprecision(2)<<max<<",between p["<<tag1<<"] and p["<<tag2<<"]."<<endl;
delete []p;
}
}
E. 点圆运算(构造与析构)
题目描述
设计一个点类Point,包含私有属性x坐标和y坐标,操作包括
1、构造函数,要求满足两个条件:1.能够使用类Point去创建一个对象数组(缺省构造方法!);2.能够接收外来输入的x和坐标做初始化,提示:构造函数重载
2、析构函数,把x坐标和y坐标都清0,并输出信息“point clear”
3、设置(setXY),接受外来输入,并设置x坐标和y坐标
4、获取x坐标,直接返回x值
5、获取y坐标,直接返回y值
设计一个圆类Circle,包含私有属性:圆心坐标x和y、半径r;操作包括:
1、构造函数,接受外来输入,设置圆心x坐标、y坐标和半径
2、析构函数,将圆心坐标x和y以及半径都清零,并输出"circle clear"
3、包含(Contain),判断一个圆是否包含一个点,计算圆心到这个点的距离,然后和半径做比较,大于则不包含,小于等于则包含。提示:用点对象做参数不一定符合输出
输入
第一行输入一个点的x坐标和y坐标,用Point类去创建一个点对象,并且自动通过构造函数来初始化
第二行输入n,用Point类去创建一个点对象数组,包含n个点
第三行起输入n行,每行输入一个点的x和y坐标,使用设置(setXY)来设置每个点的x和y坐标
接着一行输入三个参数,表示一个圆的圆心坐标x和y,以及半径,使用Circle类去创建一个圆对象,并自动通过构造函数来初始化
输出
通过调用圆的包含(Contain)方法,判断每个点是否在圆内。
按照点的输入顺序,每行输出一个点的判断结果,如果包含则输出in,不包含则输出out
说明:当一个对象数组是动态创建的,那么在程序结束时,这个数组是不会被回收。只有增加代码delete []p,才会回收数组。
本题不要求收回数组.
输入样例
5 2
3
4 7
9 9
2 4
3 3 3
输出样例
in
out
out
in
circle clear
point clear
参考代码
#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;
class Point
{
int x,y;
public:
Point()//缺省构造函数
{
x=0;
y=0;
}
~Point()
{
x=0;
y=0;
cout<<"point clear"<<endl;
}
Point(int x_value,int y_value)//有参构造函数
{
x=x_value;
y=y_value;
}
int getX()//返回x的值
{
return x;
}
int getY()//返回y的值
{
return y;
}
void setXY(int x1,int y1)//设置数组里的x,y
{
x=x1;
y=y1;
}
};
class Circle
{
int x;int y;int r;
public:
Circle(int x1,int y1,int r1)
{
x=x1;
y=y1;
r=r1;
}
~Circle()
{
x=0;
y=0;
r=0;
cout<<"circle clear"<<endl;
}
void setXY(int x1,int y1,int r1)
{
x=x1;
y=y1;
r=r1;
}
void contain(int x1,int y1)
{
if(sqrt((x1-x)*(x1-x)+(y1-y)*(y1-y))<=r) cout<<"in"<<endl;
else cout<<"out"<<endl;
}
};
int main()
{
int n;//点的个数
int p1_x,p1_y,x,y;//点的坐标
int cir_x,cir_y,r;//圆心的坐标 ,半径
cin>>p1_x>>p1_y;
Point p1(p1_x,p1_y);
cin>>n;
Point *p=new Point[n];
for(int i=0;i<n;i++)
{
cin>>x>>y;
p[i].setXY(x,y);
}
cin>>cir_x>>cir_y>>r;
Circle c(cir_x,cir_y,r);//初始化
c.contain(p1_x,p1_y);
for(int i=0;i<n;i++)
{
x=p[i].getX();
y=p[i].getY();
c.contain(x,y);
}
//delete []p;
}