一、实验目的
1. 掌握函数模板与类模板;
2. 掌握数组类、链表类等线性群体数据类型定义与使用;
二、实验任务
1. 分析完善以下程序,理解模板类的使用:
(1)补充类模板声明语句。
(2)创建不同类型的类对象,使用时明确其数据类型?
_template<typename T>____________________ //声明类模板
class A
{
public:
A(T t){ this->t = t; }
T &getT(){ return t;}
void printAA(){cout<<t;}
private:
T t; //类中数据成员类型参数化
};
void main()
{
//模板中如果定义了构造函数,则遵守以前的类的构造函数的调用规则
___A<int> a(1)_______________; //创建数据成员是整型的基类对象a
a.getT();
a.printAA();
__A<double> b(1.1); ________________; //创建数据成员是double类型的的基类对象b
______ b.getT();
b.printAA();____________; //输出对象b的信息
}
实验思考题回答与结果分析:
(1)程序运行结果:1和1.1。
(2)该程序主要运用.........知识点?编程时需要注意什么?(不要抄袭!)
该程序主要运用了模板类的知识点。需要注意的是,使用模板类时需要在类名称后面加上尖括号<>,并在其中指定数据类型,即类实例化。同时,在创建对象时需要明确其数据类型,并传递相应的构造函数参数。
- 设计一个分数类 CFraction,再设计一个求数组中最大值的函数模板,并用该模板求一个 CFmction 数组中的最大元素。
参考代码:
#include <iostream>
using namespace std;
//分数类
class CFraction {
int numerator, denominator; //分子分母
public:
CFraction(int n, int d) :numerator(n), denominator(d) { };
bool operator <(const CFraction & f) const
{ //为避免除法产生的浮点误差,用乘法判断两个分数的大小关系
if (denominator * f.denominator > 0)
return numerator * f.denominator < denominator * f.numerator;
else
return numerator * f.denominator > denominator * f.numerator;
}
bool operator == (const CFraction & f) const
{ //为避免除法产生的浮点误差,用乘法判断两个分数是否相等
return numerator * f.denominator == denominator * f.numerator;
}
friend ostream & operator <<(ostream & o, const CFraction & f);
};
template <class T> //声明函数模板
T MaxElement(T a[], int size) //定义函数体
{
//函数功能:找出数组中的最大值
.............. //补充代码
}
ostream & operator <<(ostream & o, const CFraction & f) //重载 << 使得分数对象可以通过cout输出
{
________________________; //补充代码,输出"分子/分母" 形式
return o;
}
int main()
{
int a[5] = { 1,5,2,3,4 };//定义整数数组
CFraction f[4] = { CFraction(8,6),CFraction(-8,4),
CFraction(3,2), CFraction(5,6) };//定义分数类数组对象
___________________________;//调用模板函数MaxElement输出整数数组a的最大值
__________________________________; //调用模板函数MaxElement和重载运算符函数”<<”输出分数数组对象的最大值
return 0;
}
程序代码:
#include <iostream>
using namespace std;
//定义分数类
class CFraction {
public:
CFraction(int numerator = 0, int denominator = 1) : m_numerator(numerator), m_denominator(denominator) {}
int getNumerator() const { return m_numerator; }
int getDenominator() const { return m_denominator; }
private:
int m_numerator; //分子
int m_denominator; //分母
};
//定义比较函数模板
template<typename T>
T getMax(T arr[], int n) {
T maxVal = arr[0];
for (int i = 1; i < n; i++) {
if (arr[i] > maxVal) {
maxVal = arr[i];
}
}
return maxVal;
}
int main() {
CFraction arr[] = { CFraction(3,4), CFraction(2,5), CFraction(7,8) };
cout << "The maximum fraction is: " << getMax(arr, 3).getNumerator() << "/" << getMax(arr, 3).getDenominator() << endl;
return 0;
}
实验思考题回答与结果分析:
- 程序运行结果:
- 该程序主要运用.........知识点?编程时需要注意什么?(不要抄袭!)
在上面的例子中,我们首先定义了一个CFraction类来表示分数,然后定义了一个求最大值的函数模板getMax()
,其中arr[]
表示待比较的数组,n
表示数组元素个数,返回值为最大值。在main函数中,我们创建了一个CFraction类型的数组,并调用getMax()
模板函数来获取最大值。
- 定义链表模板类,使其具备插入结点,输出结点等功能,现要求:(1)创建链表(2)从键盘输入一个待查找整数,在链表中查找该数,找到后修改;(3)遍历链表。
参考代码:
//定义结点模板类
template <class T> //前置申明模板类
class Node //定义一个Node类
{
public:
Node(T _value) //构造函数
{
value = _value;
next = NULL;
}
public:
T value; //结点数据域
Node *next; //结点指针域,指向后继结点
} ;
//定义链表模板类
template <class T> //申明模板类
class List //定义List类
{
public:
List()
{
ptr_head=NULL; //初始化链表头结点
ptr_tail=NULL; //初始化链表尾结点