西安石油大学C++上机实验 上机五:模板和异常处理程序设计(2 学时)

简介: 西安石油大学C++上机实验 上机五:模板和异常处理程序设计(2 学时)

上机五:模板和异常处理程序设计(2 学时)

实验目的

1.了解参数多态性的概念。

2.熟悉函数模板和类模析的设计和使用方法。

3.掌握 C++异常处理方法和异常类的设计。

了解参数多态性的概念。

熟练掌握函数模板和类模析的设计和使用方法。

实验内容

P197:7.9

设计一个考虑异常情况的分数类模板,实现基本分数运算和分数的输出,并编写测试程序进行测试。

测试例题

[例 7.2] 设计一下复数类模板。要求:

(1)复数类模板的成员函数包括加和输出;

(2)成员函数加既可以是两个复数类模板对象相加,也可以是一个复数类模板对象与另一个模板参数作为实部的数值相加;

(3)设计一个测试主函数,要求测试主函数中同时定义实参为 float 的复数类对象和实参为 double 的复数类对象。

// TemplateComplex.h
template <class T>
class Complex{
 T real;
 T imag;
public:
 Complex(T x=0, T y=0);
 Complex Add(const Complex x);
 Complex Add(const T x);
void show() const;
};
template <class T>
Complex<T>::Complex(T x, T y)
{
real = x;
imag = y;
}
template <class T>
Complex<T> Complex<T>::Add(const Complex<T> x)
{
return Complex<T>(real+x.real, imag+x.imag);
}
template <class T>
Complex<T> Complex<T>::Add(const T x)
{
return Complex<T>(real+x, imag);
}
template <class T>
void Complex<T>::show() const
{
cout<<"real is "<<real;
cout<<" imag is "<<imag<<endl;
}
在主文件中 work5.cpp 中编辑测试代码:
#include <iostream.h>
#include "TemplateComplex.h"
int main(int argc, char* argv[])
{
Complex<float> x(1.1, 1.1), y(2.2, 2.2), z;
Complex<double> u(1.111111, 1.111111), v(2.22222, 2.22222), w;
z = x.Add(y);
cout<<"z is: ";
z.show();
w = u.Add(v);
cout<<"w is: ";
w.show();
return 0;
}
[例 7.3] 设计一个求两个数中较大数的函数模板
//Max.h
template <class T>
T max(T x, T y)
{
 return (x>y)? x:y;
}
在主文件中 work5.cpp 中编辑测试代码:
#include <iostream.h>
#include "Max.h"
int main(int argc, char* argv[])
{
int myIntX = 5, myIntY = 8, myIntC;
float myFloatX = 5.6, myFloatY = 8.9, myFloatC;
54
myIntC = max(myIntX, myIntY);
cout<<"myIntC = "<<myIntC<<endl;
myFloatC = max(myFloatX, myFloatY);
cout<<"myFloatC = "<<myFloatC<<endl;
}
//SeqStack.h
class PushOnFull{ //入栈满异常类
 int value;
public:
 PushOnFull(int x) : value(x){}
 int Value(void){ return value; }
};
class PopOnEmpty{};
class SeqStack{
int *data;
int MaxStackSize;
int top;
public:
SeqStack(int n)
{
top = 0;
MaxStackSize = 0;
data = new int[n];
}
~SeqStack(){ delete data; }
void Push(const int item);
int Pop();
};
void SeqStack::Push(const int item)
{
 if(top==MaxStackSize)
 throw PushOnFull(item);
 data[top] = item;
 top++;
}
int SeqStack::Pop()
{
if(top == 0) throw PopOnEmpty();
top--;
return data[top];
}
在主文件中 work5.cpp 中编辑测试代码:
#include <iostream.h>
#include "SeqStack.h"
int main(int argc, char* argv[])
{
SeqStack myStack(10);
try{
for(int i=0; i<11; i++)
myStack.Push(i+1);
}
catch(PushOnFull obj){
cout<<"Stack is full"<<endl;
cout<<"the element is: "<<obj.Value()<<endl;
}
try{
for(int i=0; i<11; i++)
cout<<myStack.Pop()<<" ";
}
catch(PopOnEmpty){
cout<<"Stack is empty"<<endl;
}
}

P197:7.9

设计一个考虑异常情况的分数类模板,实现基本分数运算和分数的输出,并编写测试程序进行测试。

class Fract{
public:
int n; //分子
int m; //分母
 Fract(int a=0, int b=1):n(a), m(b){}
 Fract Add(const Fract x);
Fract Div(const Fract x);
void show() const;
int MaxComm(int a, int b);
};
Fract Fract::Div(const Fract x)
{
57
58
int a = n*x.m;
int b = m*x.n;
if(b == 0)throw 0;
int c = MaxComm(a, b);
return Fract(a/c, b/c);
}
Fract Fract::Add(const Fract x)
{
int a = n*x.m + m*x.n;
int b = m*x.m;
int c = MaxComm(a, b);
return Fract(a/c, b/c);
}
int Fract::MaxComm(int a, int b)//求 a,b 的最大公约数
{
int r=a%b;
while(r!=0)
{
a = b;
b = r;
r = a%b;
}
return(b);
}
void Fract::show() const
{
cout<<n<<"/"<<m<<endl;
}
(3)在主文件中 work5.cpp 中编辑测试代码:
#include <iostream.h>
#include "Fract.h"
int main(int argc, char* argv[])
{
Fract f1(3, 4), f2(7, 16), f3;
try{
59
f1.Div(f3);
}
catch(int){
cout<<"Divided by Zero!"<<endl;
}
f3 = f1.Add(f2);
f3.show();
}

CHATgpt 会怎么来处理?

好的,下面是一个考虑异常情况的分数类模板,并实现了基本分数运算和分数输出的代码:
~~~c++
#include<iostream>
#include<exception>
using namespace std;
//自定义除数为0异常
struct DIVBYZERO: public exception
{
    const char* what() const throw()
    {
        return "Error: Division by zero!\n";
    }
};
template<class T>
class Fraction
{
    private:
        T numerator; // 分子
        T denominator; // 分母
    public:
        // 构造函数
        Fraction(T num, T den);
        // getter 方法
        T getNumerator();
        T getDenominator();
        // setter 方法
        void setNumerator(T num);
        void setDenominator(T den);
        // 重载"+"
        Fraction operator+(Fraction f);
        // 重载"-"
        Fraction operator-(Fraction f);
        // 重载"*"
        Fraction operator*(Fraction f);
        // 重载"/"
        Fraction operator/(Fraction f);
        // 输出分数
        void print();
};
// 构造函数实现
template<class T>
Fraction<T>::Fraction(T num, T den)
{
    if(den == 0) // 如果分母为0则抛出DIVBYZERO异常
        throw DIVBYZERO();
    numerator = num;
    denominator = den;
}
// getter 方法实现
template<class T>
T Fraction<T>::getNumerator()
{
    return numerator;
}
template<class T>
T Fraction<T>::getDenominator()
{
    return denominator;
}
// setter 方法实现
template<class T>
void Fraction<T>::setNumerator(T num)
{
    numerator = num;
}
template<class T>
void Fraction<T>::setDenominator(T den)
{
    // 如果分母为0则抛出DIVBYZERO异常
    if(den == 0)
        throw DIVBYZERO();
    else
        denominator = den;
}
// 重载"+" 实现
template<class T>
Fraction<T> Fraction<T>::operator+(Fraction f)
{
    T num = numerator * f.denominator + f.numerator * denominator;
    T den = denominator * f.denominator;
    return Fraction(num, den);
}
// 重载"-" 实现
template<class T>
Fraction<T> Fraction<T>::operator-(Fraction f)
{
    T num = numerator * f.denominator - f.numerator * denominator;
    T den = denominator * f.denominator;
    return Fraction(num, den);
}
// 重载"*" 实现
template<class T>
Fraction<T> Fraction<T>::operator*(Fraction f)
{
    T num = numerator * f.numerator;
    T den = denominator * f.denominator;
    return Fraction(num, den);
}
// 重载"/" 实现
template<class T>
Fraction<T> Fraction<T>::operator/(Fraction f)
{
    // 如果除数为0则抛出DIVBYZERO异常
    if(f.numerator == 0)
        throw DIVBYZERO();
    T num = numerator * f.denominator;
    T den = denominator * f.numerator;
    return Fraction(num, den);
}
//输出分数
template<class T>
void Fraction<T>::print()
{
    cout << " " << numerator << "/" << denominator << " ";
}
//测试
int main()
{
    try
    {
        Fraction<int> f1(3,8), f2(1,4);
        Fraction<int> f3 = f1 + f2;
        Fraction<int> f4 = f1 - f2;
        Fraction<int> f5 = f1 * f2;
        Fraction<int> f6 = f1 / f2;
        cout << "f1:"; f1.print(); cout << endl;
        cout << "f2:"; f2.print(); cout << endl;
        cout << "f1+f2:"; f3.print(); cout << endl;
        cout << "f1-f2:"; f4.print(); cout << endl;
        cout << "f1*f2:"; f5.print(); cout << endl;
        cout << "f1/f2:"; f6.print(); cout << endl;
        Fraction<double> f7(3.2, 1.5), f8(0, 4);
        Fraction<double> f9 = f7 + f8;
    }
    catch(DIVBYZERO &e)
    {
        cout << e.what() <<endl;
    }
    return 0;
~~~`
代码上注释已经比较详细了,主要实现了以下功能:
1. 自定义除数为 0 异常(DIVBYZERO)。
2. 分别用构造函数和 setter 方法对分子和分母进行初始化,并提供 getter 方法获取成员变量值。
3. 实现基本分数运算符重载( + , - , \* , / )。
4. 实现分数的输出功能。
在测试程序中,我们创建了两个不同数据类型的分数类(int 型和 double 型),并对其+、-、\*、/四种运算符进行了使用。同时,也考虑到了除数为 0 时抛出错误处理。
目录
相关文章
|
17小时前
|
C++
【期末不挂科-C++考前速过系列P6】大二C++实验作业-模板(4道代码题)【解析,注释】
【期末不挂科-C++考前速过系列P6】大二C++实验作业-模板(4道代码题)【解析,注释】
【期末不挂科-C++考前速过系列P6】大二C++实验作业-模板(4道代码题)【解析,注释】
|
23小时前
|
存储 算法 C++
详解C++中的STL(标准模板库)容器
【4月更文挑战第30天】C++ STL容器包括序列容器(如`vector`、`list`、`deque`、`forward_list`、`array`和`string`)、关联容器(如`set`、`multiset`、`map`和`multimap`)和容器适配器(如`stack`、`queue`和`priority_queue`)。它们为动态数组、链表、栈、队列、集合和映射等数据结构提供了高效实现。选择合适的容器类型可优化性能,满足不同编程需求。
|
2天前
|
存储 C++
C++ 异常处理机制详解:轻松掌握异常处理技巧
C++ 异常处理提供结构化错误管理,增强程序健壮性。通过`throw`抛出异常,`try-catch`捕获并处理。示例展示了当年龄小于18时抛出异常。优点包括提高健壮性和代码可维护性,但可能降低性能并复杂化代码。另外,介绍了四种在C++中相加两个数的方法,包括使用运算符、函数、类、STL函数和lambda表达式。
10 0
|
2天前
|
运维 Serverless Go
Serverless 应用引擎产品使用之在阿里云函数计算中c++模板,将编译好的C++程序放进去部署如何解决
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
9 1
|
2天前
|
存储 C++
【C++模板】模板实现通用的数组
【C++模板】模板实现通用的数组
|
7天前
|
安全 编译器 C++
C++从入门到精通:3.2异常处理——掌握C++的异常处理机制,提高程序健壮性
C++从入门到精通:3.2异常处理——掌握C++的异常处理机制,提高程序健壮性
|
7天前
|
编译器 程序员 C++
C++从入门到精通:3.1模板编程——提高代码的复用性和灵活性
C++从入门到精通:3.1模板编程——提高代码的复用性和灵活性
|
7天前
|
程序员 编译器 C语言
【C++高阶(七)】C++异常处理的方式
【C++高阶(七)】C++异常处理的方式
|
7天前
|
编译器 C语言 C++
【C++进阶(七)】仿函数深度剖析&模板进阶讲解
【C++进阶(七)】仿函数深度剖析&模板进阶讲解
|
1天前
|
存储 Java C++
【C++类和对象】探索static成员、友元以及内部类
【C++类和对象】探索static成员、友元以及内部类