0
点赞
收藏
分享

微信扫一扫

《C++程序设计实践》实验十[期中]

兽怪海北 2022-04-21 阅读 72
c++

1.【描述】
请根据main函数中对该类的操作,补充类实现部分完成代码。
该类有个私有静态变量count记录该类的所有对象数,主函数将会在不同语句之后输出对象数,只有正确地实现该类,保证count正确记录该类的对象数,才能输出正确的结果。
【输入】
没有输入。
【输出】
主函数的输出已经写好。

#include <iostream>
#include <string>
using namespace std;
class Student {
private:
    int id;
    static int count; 
public:
/* 请在此处编写相关代码 */
static void InitCount(){
    count=0;
}

Student(){
    count++;
}
Student(int a){
    id=a;
    count++;
}
Student(const Student &stu){
    id=stu.id;
    count++;
}
~Student(){
    count--;
}

friend void PrintCount();
friend void Print(Student s);
};
int Student::count;
void PrintCount() {
    cout << "Total " << Student::count << " students" << endl;
}
void Print(Student s) {
    cout << "the id is " << s.id << endl;
}
int main() {
    Student::InitCount();
    Student s;
    PrintCount();
    Student s1(10);
    Student s2(s1);
    PrintCount();
    Print(s2);	// 调用拷贝构造函数,调用结束调用析构函数 
    PrintCount();
    return 0;
}

2.【描述】
我们都知道,对于一个表达式可以这么写:1+2-3+4
那我们是否也可以这样想,在对象的层次上能不能也有这样类似的级联(链式)调用来完成这样的功能呢?
例如上边的表达式可以变成如下格式:
Number op(1);
op.add(2).sub(3).add(4)
op.print();         //在一行上输出最终结果:4
注意:本题所涉及的类型均为int型,无需考虑其他类型。
现在你被安排完成这样一个级联调用的功能,给定类Number,请你完成其中的add方法和sub方法,这两个方法分别接受一个int型的参数,此外Number还有一个有参构造函数,接受的参数也是int型,最后你需要实现一个print的方法,用于打印结果。
【输入】
输入在一行中给出三个整数a、b、c,以空格间隔。
【输出】
输出a-b+c的结果。
【输入示例】
1 3 5
【输出示例】
3

#include<iostream>
using namespace std;
class Number {
public:
    Number();
    Number(int value);
    Number& add(int num);
    Number& sub(int num);
    void print();
private:
    int value;
};
Number::Number() {//无参构造函数,对象的默认值为0
    value = 0;
}
Number::Number(int value) {//有参构造函数
    this->value = value;
}
Number& Number::add(int num) {//加法
    this->value += num;
    return *this;
}
Number& Number::sub(int num) {//减法
    this->value -= num;
    return *this;
}
void Number::print() {//输出对象的值
    cout << value << endl;
}

int main() {
    int a, b, c;
    cin >> a >> b >> c;
    Number n(a);
    n.sub(b).add(c);
    n.print();
    return 0;
}

3.【描述】
声明并实现一个带下标越界检查的TwoArray类,表示二维数组(矩阵),存放整数。TwoArray类包括:
int类型的指针pArray,指向存放数组元素的动态分配内存空间。
int类型的私有数据成员rowSize,存放数组行长度。
int类型的私有数据成员columnSize,存放数组列长度。
有参构造函数,将数组行、列长度设置为给定的参数,并动态分配对应的内存空间。
拷贝构造函数。
析构函数。
重载赋值运算符。
重载函数调用运算符。
两个访问器函数getRowSize和getColumnSize,用于获取数组行、列长度。
函数调用运算符()必须以成员函数形式进行重载。假设matrix是TwoArray类的对象,重载函数调用运算符的意图是使用matrix(i, j)这样的形式来访问二维数组元素,而不是原来的matrix[i][j]的形式。
重载函数调用运算符的语法如下:
   函数类型operator()(参数表);
和重载下标运算符一样,在twoArray类中,重载函数调用运算符有两种形式:
       int &operator()(int row, int column);
以及:
       int operator()(int row, int column)const;
定义普通函数:void printTwoArray(const TwoArray &array)
按行输出二维数组,每个元素宽度为3。
【输入】
输入一个3×4矩阵和一个4×4矩阵。
【输出】
见【输出示例】
【输入示例】
0 1 2 3
2 3 4 5
4 5 6 7
0 1 2 3
3 4 5 6
6 7 8 9
9 10 11 12
【输出示例】
array1:
  0  1  2  3
  2  3  4  5
  4  5  6  7
array2:
  0  1  2  3
  3  4  5  6
  6  7  8  9
  9 10 11 12
array3:
  0  1  2  3
  2  3  4  5
  4  5  6  7
Row index out of range!
array1:
  0  1  2  3
  3  4  5  6
  6  7  8  9
  9 10 11 12
【来源】
《程序设计基础——以C++为例》第6章实验4。

#include <iostream>
#include <iomanip>
#include <stdexcept>
using namespace std;
/* 请在此处编写TwoArray类 */
class TwoArray{
	public:
		TwoArray(int newRowSize,int newColumnSize){
			rowSize = newRowSize;
			columnSize = newColumnSize;
			pArray = new int*[rowSize];
			for(int i = 0; i<rowSize;i++){
				pArray[i] = new int[columnSize];	
			}
		}
		int getRowSize()const{
			return rowSize;
		}
		int getColumnSize()const{
			return columnSize;
		}
		int &operator ()(int row,int column){
			if(row>=rowSize){
				throw out_of_range("Row index out of range!");;
			}
			else if(column >=columnSize){
				throw out_of_range("Column index out of range!");
			}
			else{
				return pArray[row][column];
			}
			
		}
		
	private:
		int rowSize;
		int columnSize;
		int **pArray;
		
};
void printTwoArray(TwoArray &array){
	for(int i = 0; i< array.getRowSize();i++){
		for(int j = 0; j< array.getColumnSize();j++){
			cout << right << setw(3)<< array(i,j);
		}
		cout << endl;
	}
}
int main() {
    TwoArray array1(3, 4);
    for(int i = 0; i < array1.getRowSize(); ++i)
        for(int j = 0; j < array1.getColumnSize(); ++j)
            cin >> array1(i, j);
    cout << "array1:" << endl;
    printTwoArray(array1);
    TwoArray array2(4, 4);
    for(int i = 0; i < array2.getRowSize(); ++i)
	for(int j = 0; j < array2.getColumnSize(); ++j)
	    cin >> array2(i, j);
    cout << "array2:" << endl;
    printTwoArray(array2);
    TwoArray array3(array1);
    cout << "array3:" << endl;
    printTwoArray(array3);
    try {
	array1(3, 4) = 1000;
    }
    catch(out_of_range &ex) {
	cout << ex.what() << endl;
    }
    array1 = array2;
    cout << "array1:" << endl;
    printTwoArray(array1);
    return 0;
}

4.【描述】
声明和实现一个向量类MyVector,包括一个点的坐标位置x、y和z,实现其构造函数和三个友元函数,完成两个向量的加法、减法、点乘与叉乘运算。
【输入】
输入一个点的坐标位置x、y和z。
【输出】
见【输出示例】
【输入示例】
3 4 5
【输出示例】
(1,0,0)
(-1,-3,0)
(15,-10,-1)
18

#include <iostream>
using namespace std;
class MyVector {
public:
    MyVector(int = 0, int = 0, int = 0);
    MyVector(const MyVector &);
    void display();
    friend MyVector add(MyVector &v1, MyVector &v2);    // 向量加法
    friend MyVector sub(MyVector &v1, MyVector &v2);    // 向量减法
    friend int dot(MyVector &v1, MyVector &v2);         // 向量点乘
    friend MyVector cross(MyVector &v1, MyVector &v2);  // 向量叉乘
private:
    int x, y, z;
};
/* 请在此处编写相关代码 */
MyVector::MyVector(int a,int b,int c){
	x = a;
	y = b;
	z = c;
} 
MyVector::MyVector(const MyVector &v){
	x = v.x;
	y = v.y;
	z = v.z;
}
void MyVector::display(){
	cout<<"("<<this->x<<","<<this->y<<","<<this->z<<")"<<endl;
}
MyVector add(MyVector &v1, MyVector &v2){
	MyVector my(v1.x+v2.x,v1.y+v2.y,v1.z+v2.z);
	return my; 
}
MyVector sub(MyVector &v1, MyVector &v2){
	MyVector my(v1.x-v2.x,v1.y-v2.y,v1.z-v2.z);
	return my;
}
int dot(MyVector &v1, MyVector &v2){
	return v1.x*v2.x+v1.y*v2.y+v1.z*v2.z;
}
MyVector cross(MyVector &v1, MyVector &v2){
	MyVector my(v1.y*v2.z-v2.y*v1.z,v1.z*v2.x-v2.z*v1.x,v1.z*v2.y-v2.x*v1.y);
	return my;
}
int main() {
    int x, y, z;
    cin >> x >> y >> z;
    MyVector a;
    MyVector b(1);
    MyVector c(2, 3); 
    MyVector d(x, y, z);
    MyVector e(c);
    MyVector xx = add(a, b);
    xx.display();
    MyVector yy = sub(b, c);
    yy.display();
    MyVector zz = cross(c, d);
    zz.display();
    int w = dot(d, e);
    cout << w << endl;
    return 0;
}

5.【描述】
以成员函数的形式重载关系运算符(<、<=、==、!=、>、>=),使用半径比较Circle对象大小。
【输入】
输入一行,两个圆半径,圆半径以空格间隔。
【输出】
分行输出圆半径对应的圆对象的比较结果。
【输入示例】
5 6
【输出示例】
true
true
false
true
false
false
【提示】
Circle类可以参阅《程序设计基础——以C++为例》第5章【例5.1】。
【来源】
《程序设计基础——以C++为例》第6章实验3。

#include <iostream>
using namespace std;
const double PI = 3.14159;
class Circle
{
private:
	double radius;
public:
	//构造函数声明
	Circle();
	//括号形式赋值方法声明
	Circle(double input_radius);
	//Get半径方法声明
	double Get_Radius();
	//赋值运算符(一个变量赋值给另一个变量)重载声明
	Circle& operator = (const Circle& other);
	//赋值运算符(一个double数赋值)重载声明
	Circle& operator = (double other_radius);
	//关系运算符==(raidus之间比较)重载声明
	bool operator == (const Circle& other);
	//关系运算符==(radius与数之间比较)重载声明
	bool operator == (double other_radius);
	//关系运算符>重载声明
	bool operator > (const Circle& other);
	//关系运算符<重载声明
	bool operator < (const Circle& other);
	//关系运算符>=重载声明
	bool operator >= (const Circle& other);
	//关系运算符<=重载声明
	bool operator <= (const Circle& other);
	//关系运算符!=重载声明
	bool operator != (const Circle& other);
	//输出流运算符重载声明
	friend ostream& operator << (ostream& output, Circle& c);
	//输入流运算符重载声明
	friend istream& operator >> (istream& input, Circle& c);
};
//构造函数初始化radius方法
Circle::Circle()
{
	this->radius = 0;
}
//括号形式赋值方法实现
Circle::Circle(double input_radius)
{
	this->radius = input_radius;
}
//Get半径方法
double Circle::Get_Radius()
{
	return this->radius;
}
//赋值运算符(一个变量赋值给另一个变量)重载实现
Circle& Circle::operator = (const Circle& other)
{
	this->radius = other.radius;
	return *this;
}
//赋值运算符(一个double数赋值)重载实现
Circle& Circle::operator = (double other_radius)
{
	this->radius = other_radius;
	return *this;
}
//关系运算符==(raidus之间比较)重载
bool Circle::operator == (const Circle& other)
{
	//如果半径等于右侧Circle对象的半径
	if ((this->radius) == other.radius)
	{
		//返回真
		return true;
	}
	//如果半径不等于右侧Circle对象的半径
	else
	{
		//返回假
		return false;
	}
}
//关系运算符==(radius与数之间比较)重载实现
bool Circle::operator == (double other_radius)
{
	//如果右值相等
	if ((this->radius) == other_radius)
	{
		//返回真
		return true;
	}
	//否则
	else
	{
		//返回假
		return false;
	}
}

//关系运算符>重载实现(实现方法与==雷同)
bool Circle::operator > (const Circle& other)
{
	if ((this->radius > other.radius))
	{
		return true;
	}
	else
	{
		return false;
	}
}
//关系运算符<重载实现
bool Circle::operator < (const Circle& other)
{
	if ((this->radius < other.radius))
	{
		return true;
	}
	else
	{
		return false;
	}
}
//关系运算符!=重载实现
bool Circle::operator != (const Circle& other)
{
	if ((this->radius !=other.radius))
	{
		return true;
	}
	else
	{
		return false;
	}
}
//关系运算符>=重载实现
bool Circle::operator >= (const Circle& other)
{
	if ((this->radius >= other.radius))
	{
		return true;
	}
	else
	{
		return false;
	}
}
//关系运算符<=重载实现
bool Circle::operator <= (const Circle& other)
{
	if ((this->radius <= other.radius))
	{
		return true;
	}
	else
	{
		return false;
	}
}
//输出流运算符重载实现
ostream& operator << (ostream& output, Circle& c)
{
	output << c.radius;
	return output;
}
//输入流运算符重载实现
istream& operator >> (istream& input, Circle& c)
{
	input >> c.radius;
	return input;
}
int main() {
    double radius1, radius2;
    cin >> radius1 >> radius2;
    Circle c1(radius1);
    Circle c2(radius2);
    cout << boolalpha;
    cout << (c1 < c2) << endl;
    cout << (c1 <= c2) << endl;
    cout << (c1 == c2) << endl;
    cout << (c1 != c2) << endl;
    cout << (c1 > c2) << endl;
    cout << (c1 >= c2) << endl;
    return 0;
}

6.【描述】
声明并实现一个Line类,表示线段。Line类包括:
Point类的私有对象数据成员start和end,表示线段的两个端点。
有参构造函数,将线段端点设置为给定的参数。
成员函数slope,计算线段的斜率。
【输入】
输入4个数,分别表示点1坐标(x1, y1)和点2坐标(x2, y2)。
【输出】
输出直线的斜率。
【输入示例】
10 20 30 70
【输出示例】
2.5
【提示】
Point类可以参阅《程序基础基础——以C++为例》第5章实验1。
【来源】
《程序设计基础——以C为例》第6章实验1。

#include <iostream>
#include <cmath>
using namespace std;
class Line;
class Point {

private:
    double start;
    double end;
public:
    friend Line;
    Point(double& x, double& y) {
        start = x;
        end = y;
    }
};

class Line {
private:
    double k;
public:
    Line(const Point& x, const Point& y) {//复制构造函数
        k = (y.end - x.end) / (y.start - x.start);
    }

    double slope() {
        return k;
    }
};
int main() {
    double x1, y1, x2, y2;
    cin >> x1 >> y1 >> x2 >> y2;
    Point start(x1, y1);
    Point end(x2, y2);
    Line line(start, end);
    cout << line.slope() << endl;
    return 0;
}

7.【描述】
声明并实现一个类模板Pair,表示数对。类模板Pair包括:
私有数据成员first和second,first的类型为类参数T1,second的类型为类参数T2。
有参构造函数,将first和second设置为给定的参数。
访问器函数,分别返回first和second的值。
成员函数print,输出一个数对。、
成员函数swap,交换两个数对的值。
重载关系运算符<、<=、>、>=、==、!=,判断两个数对之间的关系。如果满足关系,返回true,否则返回false。
【输入】
输入二行。第一行和第二行都是一个整数、一个浮点数,表示一个数对,整数和浮点数之间以空格间隔。
【输出】
见【输出示例】
【输入示例】
1 2.5
3 4.5
【输出示例】
p1:[1,2.5]
p2:[3,4.5]
p1:[3,4.5]
p2:[1,2.5]
p1 > p2
【提示】
约定数对p1小于p2,等价于p1.first小于p2.first或者p1.first大于等于p2.first且p1.second小于p2.second。
【来源】
《程序设计基础——以C++为例》第6章实验7。

#include <iostream>
using namespace std;
template <typename T1, typename T2>
class Pair {
public:
	Pair(T1 newFirst, T2 newSecond) {
		first = newFirst;
		second = newSecond;
	}
	T1 getFirst() {
		return first;
	}
	T2 getSecond() {
		return second;
	}
	void print() {
		cout << "[" << first << "," << second << "]" << endl;
	}
	void swap(Pair<T1, T2>& number) {
		Pair<T1, T2> T = *this;
		*this = number;
		number = T;
	}
	bool operator<(const Pair<T1, T2>& right) {
		if (this->first < right.first || (this->first > right.first && this->second < right.second)) {
			return true;
		}
		else {
			return false;
		}
	}
	bool operator==(const Pair<T1, T2>& right) {
		if (this->first == right.first && this->second == right.second) {
			return true;
		}
		else {
			return false;
		}
	}
private:
	T1 first;
	T2 second;
};
int main() {
    int x1, x2;
    double y1, y2;
    cin >> x1 >> y1;
    cin >> x2 >> y2;
    Pair<int, double> p1(x1, y1), p2(x2, y2);
    cout << "p1:";
    p1.print();
    cout << "p2:";
    p2.print();
    p1.swap(p2);
    cout << "p1:";
    p1.print();
    cout << "p2:";
    p2.print();
    if(p1 < p2)
	cout << "p1 < p2" << endl;
    else if(p1 == p2)
	cout << "p1 == p2" << endl;
    else
	cout << "p1 > p2" << endl;
    return 0;
}

8.【描述】
声明并实现一个Rational类,表示有理数。有理数的+、-、×和÷运算要求通过重载运算符来实现。Rational类包括:
两个int类型的私有数据成员numerator、denominator,表示分子、分母。
一个私有成员函数gcd,用于求分子、分母的最大公约数。
一个私有成员函数compare,用于判断两个有理数之间的大小关系。一个有理数与另一个有理数相比是大于、等于还是小于,分别返回1、0和-1。
一个带默认参数值的构造函数,将分子、分母设置为给定的参数。分子、分母的默认参数值分别为0、1。
两个访问器函数getNumerator、getDenominator,分别用于获取分子、分母。
重载算术运算符+、-、*、/,实现有理数算术运算。
重载自增运算符++和自减运算符--。要同时考虑前置和后置。
重载复合算术赋值运算符+=、-=、*=、/=。
重载关系运算符<、<=、>、>=、==、!=,判断两个有理数之间的关系。如果满足关系,返回true,否则返回false。
使用类型转换函数,将有理数转换为浮点数。
重载流提取运算符>>和流插入运算符<<。输入输出一个有理数。
【输入】
输入两行。第一行为第一个有理数的分子、分母,以空格间隔。第二行为第二个有理数的分子、分母,以空格间隔。
【输出】
见【输出示例】。
【输入示例】
7 3
1 3
【输出示例】
a=7/3
b=1/3
7/3+1/3=8/3
7/3-1/3=2
7/3*1/3=7/9
7/3/1/3=7
7/3<1/3=false
7/3>1/3=true
7/3==1/3=false
7/3!=1/3=true
c=1/2
2.5+1/2=3
3/2
3/2
3/2
5/2
17/6
【来源】
《程序设计基础——以C++为例》第6章实验6。

#include <iostream>
#include <stdexcept>
using namespace std;
class Rational
{
private:
    int numerator, denominator;
public:
    //变量初始化
    Rational(int fir = 0, int sec = 1) :numerator(fir), denominator(sec)
    {

        this->denominator = denominator;
        this->numerator = numerator;
        if (denominator == 0)denominator = 1;
    }
    int getNumerator() {
        return numerator;
    }
    int getDenominator() {
        return denominator;
    }
    static int gcd(int m, int n)//计算最大公约数
    {
        while (m % n)
        {
            int temp = m;
            m = n;
            n = temp % n;
        }
        return n;
    }
    friend ostream& operator << (ostream& output, const Rational& c) {
        if (c.numerator % c.denominator == 0) {
            output << c.numerator * 1.0 / c.denominator;
        }
        else
            output << c.numerator << "/" << c.denominator;
        return output;
    }
    friend istream& operator>>(istream& in, Rational& s)
    {
        in >> s.numerator >> s.denominator;
        return in;
    }
    bool compare(const Rational& right) {
        int n = numerator * right.denominator - denominator * right.numerator;
        int d = denominator * right.denominator;
        Rational temp = Rational(n, d);
        if (temp.numerator > 0)
            return 1;
        else if (temp.numerator == 0)
            return 0;
        else
            return -1;
    }
    operator double() const {
        return numerator * 1.0 / denominator;
        //return double(this->numerator) / double(this->denominator);
    }
    bool operator > (const Rational& other) {
        return this->compare(other) > 0 ? true : false;
    }
    bool operator < (const Rational& other) {
        return this->compare(other) < 0 ? true : false;
    }
    bool operator >= (const Rational& other) {
        return this->compare(other) >= 0 ? true : false;
    }
    bool operator <= (const Rational& other) {
        return this->compare(other) <= 0?true:false;
    }
    bool operator == (const Rational& other) {
        return this->compare(other) == 0 ? true : false;
    }
    bool operator != (const Rational& other) {
        return this->compare(other) != 0 ? true : false;
    }
    friend Rational operator+(Rational& c1, const Rational& c2) {
        int fir = (c1.denominator * c2.denominator);//分母
        //分子
        int sec = (c1.numerator * c2.denominator + c2.numerator * c1.denominator);
        int m = gcd(fir, sec);
        Rational r1(sec / m, fir / m);
        if (fir / m < 0) {
            Rational r2(-1.0 * sec / m, -1.0 * fir / m);
            return r2;
        }
        else
            return r1;
    }
    friend Rational operator-(const Rational& c1, const Rational& c2) {
        int fir = c1.denominator * c2.denominator;//分母
                //分子
        int sec = c1.numerator * c2.denominator - c2.numerator * c1.denominator;
        int m = gcd(fir, sec);
        Rational r1(sec / m, fir / m);
        if (fir / m < 0) {
            Rational r2(-1.0 * sec / m, -1.0 * fir / m);
            return r2;
        }
        else
            return r1;
    }
    friend Rational operator*(const Rational& c1, const Rational& c2) {
        if (c2.numerator == 0) {
            return 0;
        }
        else {
            int fir = c1.denominator * c2.denominator;//分母
            //分子
            int sec = c1.numerator * c2.numerator;
            int m = gcd(fir, sec);
            Rational r1(sec / m, fir / m);
            if (fir / m < 0) {
                Rational r2(-1.0 * sec / m, -1.0 * fir / m);
                return r2;
            }
            else
                return r1;
        }
    }
    friend Rational operator/(const Rational& c1, const Rational& c2) {
        if (c2.numerator == 0) {
            Rational q;
            q.denominator = 0;
            q.numerator = 1;
            return q;
        }
        int fir = c1.denominator * c2.numerator;//分母
        //分子
        int sec = c1.numerator * c2.denominator;
        int m = gcd(fir, sec);
        Rational r1(sec / m, fir / m);
        if (fir / m < 0) {
            Rational r2(-1.0 * sec / m, -1.0 * fir / m);
            return r2;
        }
        else
            return r1;
    }
    Rational operator++(int)//
    {
        //后使用
        Rational temp = *this;
        numerator = numerator + denominator;
        return temp;
    }
    Rational& operator++() {
        numerator = numerator + denominator;
        return *this;
    }
    Rational& operator+= (Rational& c2)
    {
        int fir = (denominator * c2.denominator);//分母
        //分子
        int sec = (numerator * c2.denominator + c2.numerator * denominator);
        int m = gcd(fir, sec);
        this->numerator = sec / m;
        this->denominator = fir / m;
        Rational r1(sec / m, fir / m);
        return *this;
    }
};
int main() {
    Rational a, b;
    cin >> a;
    cin >> b;
    cout << "a=" << a << endl;
    cout << "b=" << b << endl;
    cout << a << "+" << b << "=" << a + b << endl;
    cout << a << "-" << b << "=" << a - b << endl;
    cout << a << "*" << b << "=" << a * b << endl;
    cout << a << "/" << b << "=" << a / b << endl;
    cout << boolalpha << a << "<" << b << "=" << (a < b) << endl;
    cout << boolalpha << a << ">" << b << "=" << (a > b) << endl;
    cout << boolalpha << a << "==" << b << "=" << (a == b) << endl;
    cout << boolalpha << a << "!=" << b << "=" << (a != b) << endl;
    Rational c(1, 2);
    cout << "c=" << c << endl;
    cout << 2.5 << "+" << c << "=" << (2.5 + c) << endl;
    cout << ++c << endl;
    cout << c << endl;
    cout << c++ << endl;
    cout << c << endl;
    cout << (c += b) << endl;
    return 0;
}

9.【描述】
声明并实现一个Time类,表示时间。Time类包括:
int类型的私有数据成员hour、minute、second,表示时、分、秒。
带默认参数的构造函数,将时、分、秒设置为给定的参数。时、分、秒的默认参数值为0。需要检查时、分、秒的有效性。如果超出允许范围,则抛出invalid_argument("Invalid argument!")异常。
访问器函数getHour、getMinute和getSecond,分别用于访问时、分、秒。
成员函数setTime,用于同时修改时、分、秒。需要检查时、分、秒的有效性。如果超出允许范围,则抛出invalid_argument("Invalid argument!")异常。
重载自增运算符++,将时间递增1秒。要考虑增加1秒后,时间增加到下一分钟、下一小时、下一天的情况。要考虑前置++和后置++。
重载关系运算符==,判断两个时间是否相等。
使用类型转换函数,将时间转换为秒数。
重载流插入运算符<<,以24小时制格式输出时间,格式为时:分:秒。
【输入】
输入一行,有3个数据,分别表示时、分、秒,以空格间隔。
【输出】
见【输出示例】
【输入示例】
23 59 57
【输出示例】
t1:23:59:57
t2:00:00:00
t1:23:59:58
t2:23:59:57
t1 != t2
86398
【来源】
《程序设计基础——以C++为例》第6章实验5。

#include <iostream>
#include <iomanip>
#include <stdexcept>
using namespace std;
class Time {
    private:
        int hour, minute, second;
    public:
        Time(int hour = 0, int minute = 0, int second = 0) {
            this->hour = hour;
            this->minute = minute;
            this->second = second;
            if (second >= 60) {
                throw invalid_argument("Invalid_argument!");
            }
        }
        void setHour(int hour) {
            this->hour = hour;
        }
        void setMinute(int minute) {
            this->minute = minute;
        }
        void setSecond(int second) {
            this->second = second;
        }
        int getHour() {
            return hour;
        }
        int getMinute() {
            return minute;
        }
        int getSecond() {
            return second;
        }
        void setTime(int hour, int minute, int second) {
            this->hour = hour;
            this->minute = minute;
            this->second = second;
        }
        Time operator++(int)//
        {
            //后使用
            Time temp = *this;
            this->second++;
            if (second == 60) {     //如果满60s了就进一位
                second = 0;
                minute += 1;
            }
            if (minute == 60) {
                minute = 0;
                hour = hour + 1;
            }
            if (hour == 24)
            {
                hour = 0;
            }
            this->hour;
            this->minute;
            return temp;
        }
        Time(const Time& str) {
            this->hour = str.hour;
            this->minute = str.minute;
            this->second = str.second;
        }

        //Time& operator==(const Time& str)
        bool operator==(const Time& str) {
            if (this == &str) {
                return 1;
            }
            return 0;
        }
        friend ostream& operator << (ostream& output, Time& c) {
            output << setw(2) << setfill('0')<< c.hour << ":";
            output << setw(2) << setfill('0') << c.minute << ":";
            output << setw(2) << setfill('0') << c.second<<endl;
            return output;
        }
        operator int() { 
            return hour*3600+minute*60+second; 
        }
};
int main() {
    int hour, minute, second;
    cin >> hour >> minute >> second;
    try {
        Time t1(hour, minute, second);
    	Time t2;
    	cout << "t1: ";
    	cout << t1;
	cout << "t2: ";
    	cout << t2;
	t2 = t1++;
	cout << "t1: ";
	cout << t1;
	cout << "t2: ";
	cout << t2;
	if(t1 == t2)
            cout << "t1 == t2" << endl;
    	else
            cout << "t1 != t2" << endl;
    	int s = t1;
    	cout << s << endl;
    }
    catch(invalid_argument &ex) {
    	cout << ex.what() << endl;	
    }
    return 0;
}

10.【描述】
第6题中的TwoArray类,表示二维数组(矩阵),只能存放整数。修改TwoArray类,使其成为一个类模板。并新增重载关系运算符==和!=,判断两个矩阵是否相等。
【输入】
输入一个3×4矩阵和一个4×4矩阵。
【输出】
见【输出示例】
【输入示例】
0 1 2 3
2 3 4 5
4 5 6 7
0 1 2 3
3 4 5 6
6 7 8 9
9 10 11 12
【输出示例】
array1:
  0  1  2  3
  2  3  4  5
  4  5  6  7
array2:
  0  1  2  3
  3  4  5  6
  6  7  8  9
  9 10 11 12
array3:
Row index out ofrange!
array1:
  0  1  2  3
  3  4  5  6
  6  7  8  9
  9 10 11 12
array1 == array2
【提示】
设置输出宽度为3。
【来源】
《程序设计基础——以C++为例》第6章实验8

#include <iostream>
#include <iomanip>
#include <stdexcept>
using namespace std;
template<typename T>
class TwoArray {
	public:
		TwoArray(int rowSize, int columnSize);
		TwoArray(const TwoArray &a);
		~TwoArray();
		const TwoArray &operator=(const TwoArray &right);
		T &operator()(int row, int column);
		T operator()(int row, int column) const;
		bool operator==(const TwoArray &right);
		bool operator!=(const TwoArray &right);
		int getRowSize() const;
		int getColumnSize() const;
	private:
		T *pArray;
		T rowSize;
		T columnSize;
};
template<typename T>
 
TwoArray<T>::TwoArray(int rowSize, int columnSize) {
	if (rowSize > 0 && columnSize > 0) {
		this->rowSize = rowSize;
		this->columnSize = columnSize;
	} else
		throw invalid_argument("Invalid argument!");
	pArray = new T[rowSize * columnSize];
}
template<typename T>
 
TwoArray<T>::TwoArray(const TwoArray &a) {
	rowSize = a.rowSize;
	columnSize = a.columnSize;
	pArray = new T[rowSize * columnSize];
	for (int i = 0; i < rowSize; ++i)
		for (int j = 0; j < columnSize; ++j)
			pArray[i * columnSize + j] = a.pArray[i * columnSize + j];
}
template<typename T>
 
TwoArray<T>::~TwoArray() {
	delete[] pArray;
}
template<typename T>
 
const TwoArray<T> &TwoArray<T>::operator=(const TwoArray &right) {
	if (this != &right) {
		if (rowSize != right.rowSize || columnSize != right.columnSize) {
			delete [] pArray;
			rowSize = right.rowSize;
			columnSize = right.columnSize;
			pArray = new T[rowSize * columnSize];
		}
		for (int i = 0; i < rowSize; ++i)
			for (int j = 0; j < columnSize; ++j)
				pArray[i * columnSize + j] = right.pArray[i * columnSize + j];
	}
	return *this;
}

template<typename T>
 
T TwoArray<T>::operator()(int row, int column) const {
	if (row < 0 || row > rowSize - 1)
		throw out_of_range("Row index out of range!");
	if (column < 0 || column > columnSize - 1)
		throw out_of_range("Column index out of range!");
	return pArray[row * columnSize + column];
}
template<typename T>
 
bool TwoArray<T>::operator==(const TwoArray &right) {
	for (int i = 0; i < rowSize; ++i)
		for (int j = 0; j < columnSize; ++j)
			if (pArray[i * columnSize + j] != right.pArray[i * columnSize + j])
				return false;
	return true;
}
template<typename T>
 
T &TwoArray<T>::operator()(int row, int column) {
	if (row < 0 || row > rowSize - 1)
		throw out_of_range("Row index out of range!");
	if (column < 0 || column > columnSize - 1)
		throw out_of_range("Column index out of range!");
	return pArray[row * columnSize + column];
}
template<typename T>
 
bool TwoArray<T>::operator!=(const TwoArray &right) {
	if (*this == right)
		return false;
	else
		return true;
}
template<typename T>
 
int TwoArray<T>::getRowSize() const {
	return rowSize;
}
template<typename T>
 
int TwoArray<T>::getColumnSize() const {
	return columnSize;
}
template<typename T>
 
void printTwoArray(const TwoArray<T> &array) {
	for (int i = 0; i < array.getRowSize(); ++i) {
		for (int j = 0; j < array.getColumnSize(); ++j)
			cout << setw(3) << array(i, j);
		cout << endl;
	}
}
int  main() {
    TwoArray<int> array1(3, 4);
    for(int i = 0;  i < array1.getRowSize(); ++i)
	for(int j = 0; j < array1.getColumnSize(); ++j)
	    cin >> array1(i, j);
    cout << "array1:" << endl;
    printTwoArray(array1);
    TwoArray<int> array2(4, 4);
    for(int i = 0; i < array2.getRowSize(); ++i)
	for(int j = 0; j < array2.getColumnSize(); ++j)
	    cin >> array2(i, j);
    cout << "array2:" << endl ;
    printTwoArray(array2);
    TwoArray<int> array3(array1);
    cout << "array3:" << endl ;
    printTwoArray(array3);
    try {
	array1(3, 4) = 1000;
    }
    catch(out_of_range &ex) {
	cout << ex.what() << endl;
    }
    array1 = array2;
    cout << "array1:" << endl ;
    printTwoArray(array1);
    if(array1 == array2)
	cout << "array1 == array2" << endl;
    else
	cout << "array1 != array2" << endl;
    return 0;
}
举报

相关推荐

0 条评论