c++复习2.模板(实验六、实验七)

该博客围绕C++的模板展开实验。实验六聚焦函数模板和类模板,包括其定义、使用及模板类实例化方法,并给出相关代码示例。实验七则探讨模板的特化和偏特化,涵盖函数模板全特化、类模板全特化与偏特化(参数数量和范围上),均有对应代码及运行结果要求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:类模板和模板类的区别

实验六 函数模板和类模板

一.实验目的

1.理解并掌握函数模板的定义和使用方法;

2.理解并掌握类模板的定义和使用方法;

3.理解并掌握模板类的应用和实例化方法;

二. 实验内容

1. 理解并掌握函数模板的定义和使用方法

第1题:请按照下面程序主函数的调用情况,定义一个加法运算的函数模板,按照注释要求完善程序。

#include <iostream>

using namespace std;

//定义加法运算函数模板

int main()

{

int x = 12;

float y = 46.9;

//cout << add(x, y) << endl;   //error,无法自动推导函数返回值

    cout << add<float>(x, y) << endl;    //返回值在第一个类型参数中指定

    cout << add<int, int, float>(x, y) << endl;

    return 0;

}

请给出完整程序的源代码,并粘贴运行结果。

#include <iostream>
using namespace std;

// 定义加法运算函数模板
template <typename T>
T add(T a, T b) {
    return a + b;
}

int main() {
    int x = 12;
    float y = 46.9;

    cout << add(x, static_cast<int>(y)) << endl;  // 显式指定模板参数
    cout << add<float>(x, y) << endl;  // 返回值在第一个类型参数中指定

    return 0;
}

2.理解并掌握类模板的定义和使用方法

第2题:定义一个矩形类模板 ,模板类中的数据成员为矩形的长和宽,其成员函数实现计算矩形的周长和面积。
 

#include <iostream>

using namespace std;

/* 定义一个矩形类模板Rect

成员函数:calcArea()、calePerimeter()

数据成员:m_length、m_height

 */

//请完成矩形类的定义

int main(void)

{

    Rect<int> rect(3, 6);

    cout <<"面积为:" <<rect.calcArea() << endl;

    cout << "周长为:"<<rect.calePerimeter() << endl;    return 0;

}

请给出完整程序的源代码,并粘贴运行结果。

#include <iostream>
using namespace std;

// 定义一个矩形类模板Rect
template <typename T>
class Rect {
private:
    T m_length;
    T m_height;

public:
    Rect(T length, T height) : m_length(length), m_height(height) {}

    // 计算矩形的面积
    T calcArea() {
        return m_length * m_height;
    }

    // 计算矩形的周长
    T calePerimeter() {
        return 2 * (m_length + m_height);
    }
};

int main(void) {
    Rect<int> rect(3, 6);
    cout <<"面积为:" <<rect.calcArea() << endl;
    cout << "周长为:"<<rect.calePerimeter() << endl;
    return 0;
}

3.理解并掌握模板类的应用和实例化方法

第3题:阅读下列关于数组类模板的定义和程序运行结果,按照注释要求补充类模板定义中相应的功能代码,以完成主函数对模板类数组的实例化调用。

#ifndef ARRAY_H_

#define ARRAY_H_

#include <cassert>

template <class T>

class Array {

private:

   T* list;

   int size;

public:

   Array(int sz = 50);

   Array(const Array<T>& a);

   ~Array();

   Array<T>& operator = (const Array<T>& rhs);

   T& operator[] (int i);

   const T& operator[] (int i) const;

   operator T* ();

   operator const T* () const;

   int getSize() const;

   void resize(int sz);

};

template <class T>

Array<T>::Array(int sz) {

   assert(sz > 0);

   size = sz;

   list = new T[size];

}

template <class T>

Array<T>::~Array() {

   delete [] list;

}

//下面补充类模板中其它成员函数声明的实现:

#endif  //ARRAY_H_

//以上为array.h头文件

#include <iostream>

#include <iomanip>

#include "array.h"

using namespace std;

void read(int *p, int n) {

 for (int i = 0; i < n; i++){

  cout << "请输入第" << i+1 <<"位学生的课程A成绩(0~100):";

cin >> p[i];

}

}

double calculate(int *p, int n) {

double total=0;

 for (int i = 0; i < n; i++)

   total += p[i];

cout << n <<"位学生的总课程为:" << total;

return total;

}

int main()

{

   int n;

   double average = 0;

   cout << "请输入学生人数:";

   cin >> n;

Array<float>  score(n);

read(score, n) ;

average = calculate(score, n)/n;

cout <<n<< "位同学的平均成绩为:" << setprecision(4) << average << endl;

return 0;

}

简而言之,就是要写以下的模板:

   Array<T>& operator = (const Array<T>& rhs);

   T& operator[] (int i);

   const T& operator[] (int i) const;

   operator T* ();

   operator const T* () const;

   int getSize() const;

   void resize(int sz);

我写的补充部分的代码:

template <class T>
Array<T>& Array<T>::operator=(const Array<T>& rhs) {
    if (this == &rhs) {
        return *this;
    }
    delete [] list;
    size = rhs.size;
    list = new T[size];
    for (int i = 0; i < size; ++i) {
        list[i] = rhs.list[i];
    }
    return *this;
}

template <class T>
T& Array<T>::operator[](int i) {
    assert(i >= 0 && i < size);
    return list[i];
}

template <class T>
const T& Array<T>::operator[](int i) const {
    assert(i >= 0 && i < size);
    return list[i];
}

template <class T>
Array<T>::Array(const Array<T>& a) {
    size = a.size;
    list = new T[size];
    for (int i = 0; i < size; ++i) {
        list[i] = a.list[i];
    }
}

template <class T>
Array<T>::operator T* () {
    return list;
}

template <class T>
Array<T>::operator const T* () const {
    return list;
}

template <class T>
int Array<T>::getSize() const {
    return size;
}

template <class T>
void Array<T>::resize(int sz) {
    assert(sz > 0);
    if (sz == size) {
        return;
    }
    T* newList = new T[sz];
    int n = (sz < size) ? sz : size;
    for (int i = 0; i < n; ++i) {
        newList[i] = list[i];
    }
    delete [] list;
    list = newList;
    size = sz;
}

参考答案:

template <class T>
Array<T>::Array(const Array<T>& a) {
    size = a.size;
    list = new T[size];
    for (int i = 0; i < size; ++i) {
        list[i] = a.list[i];
    }
}

template <class T>
Array<T>& Array<T>::operator=(const Array<T>& rhs) {
    if (&rhs != this) {
        if (size != rhs.size) {
            delete [] list;
            size = rhs.size;
            list = new T[size];
        }
        for (int i = 0; i < size; ++i) {
            list[i] = rhs.list[i];
        }
    }
    return *this;
}

template <class T>
T& Array<T>::operator[](int i) {
    assert(i >= 0 && i < size);
    return list[i];
}

template <class T>
const T& Array<T>::operator[](int i) const {
    assert(i >= 0 && i < size);
    return list[i];
}

template <class T>
Array<T>::operator T*() {
    return list;
}

template <class T>
Array<T>::operator const T*() const {
    return list;
}

template <class T>
int Array<T>::getSize() const {
    return size;
}

template <class T>
void Array<T>::resize(int sz) {
    assert(sz >= 0);

    if (sz == size)
        return;

    T* newList = new T[sz];
    int n = (sz < size) ? sz : size;
    for (int i = 0; i < n; ++i) {
        newList[i] = list[i];
    }
    delete[] list;
    list = newList;
    size = sz;
}

参考答案完整源代码:

#ifndef ARRAY_H_
#define ARRAY_H_

#include <cassert>

template <class T>
class Array {
private:
    T* list;
    int size;
public:
    Array(int sz = 50);
    Array(const Array<T>& a);
    ~Array();
    Array<T>& operator = (const Array<T>& rhs);
    T& operator[] (int i);
    const T& operator[] (int i) const;
    operator T* ();
    operator const T* () const;
    int getSize() const;
    void resize(int sz);
};

template <class T>
Array<T>::Array(int sz) {
    assert(sz > 0);
    size = sz;
    list = new T[size];
}

template <class T>
Array<T>::~Array() {
    delete [] list;
}

template <class T>
Array<T>::Array(const Array<T>& a) {
    size = a.size;
    list = new T[size];
    for (int i = 0; i < size; ++i) {
        list[i] = a.list[i];
    }
}

template <class T>
Array<T>& Array<T>::operator=(const Array<T>& rhs) {
    if (&rhs != this) {
        if (size != rhs.size) {
            delete [] list;
            size = rhs.size;
            list = new T[size];
        }
        for (int i = 0; i < size; ++i) {
            list[i] = rhs.list[i];
        }
    }
    return *this;
}

template <class T>
T& Array<T>::operator[](int i) {
    assert(i >= 0 && i < size);
    return list[i];
}

template <class T>
const T& Array<T>::operator[](int i) const {
    assert(i >= 0 && i < size);
    return list[i];
}

template <class T>
Array<T>::operator T*() {
    return list;
}

template <class T>
Array<T>::operator const T*() const {
    return list;
}

template <class T>
int Array<T>::getSize() const {
    return size;
}

template <class T>
void Array<T>::resize(int sz) {
    assert(sz >= 0);

    if (sz == size)
        return;

    T* newList = new T[sz];
    int n = (sz < size) ? sz : size;
    for (int i = 0; i < n; ++i) {
        newList[i] = list[i];
    }
    delete[] list;
    list = newList;
    size = sz;
}

#endif  // ARRAY_H_

#include <iostream>
#include <iomanip>

using namespace std;

template<typename T>
void read(Array<T>& p, int n) {
    for (int i = 0; i < n; i++) {
        cout << "请输入第" << i + 1 << "位学生的课程A成绩(0~100):";
        cin >> p[i];
    }
}

template<typename T>
double calculate(Array<T>& p, int n) {
    double total = 0;
    for (int i = 0; i < n; i++)
        total += p[i];
    cout << n << "位学生的总课程为:" << total;
    return total;
}

int main() {
    int n;
    double average = 0;
    cout << "请输入学生人数:";
    cin >> n;
    Array<float> score(n);
    read(score, n);
    average = calculate(score, n) / n;
    cout << n << "位同学的平均成绩为:" << setprecision(4) << average << endl;
	return 0;
}

实验七 模板的特化和偏特化

一.实验目的

1.理解并掌握函数模板全特化的定义和使用方法;

2.理解并掌握类模板特化和偏特化的定义和使用方法;

二. 实验内容

1. 理解并掌握函数模板全特化的定义和使用方法

第1题:请根据下面程序主函数的调用情况和程序运行结果,定义相应的全特化函数模板,按照注释要求完善程序,给出程序源代码及程序运行结果截图

//template.h

#pragma once

#include <iostream>

template <typename T, typename U>

void tfunc(T& a, U& b)

{

    std::cout << "tfunc 泛化版本函数" << std::endl;

}

// 补充相应的函数全特化代码

//main.cpp

#include <iostream>

#include "template.h"

using namespace std;

int main()

{

    int a1 = 1;

    double b1 = 3.2;

    tfunc(a1, b1);

    tfunc(a1, a1);

}

//template.h
#pragma once
#include <iostream>
template <typename T, typename U>
void tfunc(T& a, U& b)
{
	std::cout << "tfunc 泛化版本函数" << std::endl;
}
// 补充相应的函数全特化代码


//// 函数全特化1
//template <>
//void tfunc(int& a, double& b)
//{
//    std::cout << "tfunc 全特化版本函数1" << std::endl;
//}

// 函数全特化2
template <>
void tfunc(int& a, int& b)
{
    std::cout << "tfunc 全特化版本函数2" << std::endl;
}

//main.cpp
#include <iostream>
#include "template.h"
using namespace std;
int main()
{
	int a1 = 1;
	double b1 = 3.2;
	tfunc(a1, b1);
	tfunc(a1, a1);
}

运行结果截图:

2. 理解并掌握类模板全特化的定义和使用方法

第2题:请根据下面程序主函数的调用情况和程序运行结果,定义一个相应的全特化函数模板,按照注释要求完善程序,给出程序源代码及程序运行结果截图。

//template.h

#pragma once

#include <iostream>

template <typename T, typename U>

class TC

{

public:

    TC()

    {

        std::cout << "泛化版本构造函数" << std::endl;

    }

    void funtest()

    {

        std::cout << "泛化版本成员函数" << std::endl;

    }

};

// 补充相应的类全特化代码

//main.cpp

#include <iostream>

#include "template.h"

using namespace std;

int main()

{

    TC<char, int> tchar;

    tchar.funtest();

    TC<int, int> tint;

    tint.funtest();

    TC<double, double> tdouble;

    tdouble.funtest();

}

//template.h
#pragma once
#include <iostream>
template <typename T, typename U>
class TC
{
public:
	TC()
	{
		std::cout << "泛化版本构造函数" << std::endl;
	}
	void funtest()
	{
		std::cout << "泛化版本成员函数" << std::endl;
	}
};


template <>
class TC<int, int>
{
public:
	TC()
	{
		std::cout << "TC<int, int> 全特化版本构造函数" << std::endl;
	}
	void funtest()
	{
		std::cout << "TC<int, int> 全特化版本成员函数" << std::endl;
	}
};


template <>
class TC<double, double>
{
public:
	TC()
	{
		std::cout << "TC<double, double> 全特化版本构造函数" << std::endl;
	}
	void funtest()
	{
		std::cout << "TC<double, double> 全特化版本成员函数" << std::endl;
	}
};

//main.cpp
#include <iostream>
#include "template.h"
using namespace std;

int main()
{
	TC<char, int> tchar;
	tchar.funtest();
	TC<int, int> tint;
	tint.funtest();
	TC<double, double> tdouble;
	tdouble.funtest();
}

程序运行结果截图:

3. 理解并掌握类模板偏特化的定义和使用方法

(1)类模板参数数量上的偏特化

第3题:请根据下面程序主函数的调用情况和程序运行结果,定义一个相应的偏特化类模板,按照注释要求完善程序,给出程序源代码及程序运行结果截图。

//template.h

#pragma once

#include <iostream>

template <typename T, typename U, typename W>

class TC2

{

public:

    void funtest()

    {

        std::cout << "泛化版本成员函数" << std::endl;

    }

};

// 补充相应的类偏特化代码

//main.cpp

#include <iostream>

#include "template.h"

using namespace std;

int main()

{

    TC2<double, double, double> tdouble2;

    tdouble2.funtest();

    TC2<int, double, double> tint2;

    tint2.funtest();

}

//template.h
#pragma once
#include <iostream>
template <typename T, typename U, typename W>
class TC2
{
public:
	void funtest()
	{
		std::cout << "泛化版本成员函数" << std::endl;
	}
};


template <typename U>
class TC2 <int, U, double>
{
public:
	void funtest()
	{
		std::cout << "TC2 <int, U, double> 偏特化版本成员函数" << std::endl;
	}
};

//main.cpp
#include <iostream>
#include "template.h"
using namespace std;

int main()
{
	TC2<double, double, double> tdouble2;
	tdouble2.funtest();
	TC2<int, double, double> tint2;
	tint2.funtest();
}

运行结果截图:

(2)类模板参数范围上的偏特化

第4题:请根据下面程序主函数的调用情况和程序运行结果,定义一个相应的偏特化类模板,按照注释要求完善程序,给出程序源代码及程序运行结果截图。

// template.h

#pragma once

#include <iostream>

template <typename T>

class TC3

{

public:

    void funtest()

    {

        std::cout << "泛化版本成员函数" << std::endl;

    }

};

// 补充相应的类偏特化代码

//main.cpp

#include <iostream>

#include "template.h"

using namespace std;

int main()

{

    TC3<int> tint3;

    tint3.funtest();

    TC3<int&> tint3_ref;

    tint3_ref.funtest();

    TC3<int*> tint3_point;

    tint3_point.funtest();

    TC3<const int> tint3_const;

    tint3_const.funtest();

}

运行结果截图:

// template.h
#pragma once
#include <iostream>
template <typename T>
class TC3
{
public:
	void funtest()
	{
		std::cout << "泛化版本成员函数" << std::endl;
	}
};


template <typename T>
class TC3<T&>
{
public:
	void funtest()
	{
		std::cout << "T&偏特化版本成员函数" << std::endl;
	}
};


template <typename T>
class TC3<T*>
{
public:
	void funtest()
	{
		std::cout << "T*偏特化版本成员函数" << std::endl;
	}
};

template <typename T>
class TC3<const T>
{
public:
	void funtest()
	{
		std::cout << "const T偏特化版本成员函数" << std::endl;
	}
};

//main.cpp
#include <iostream>
#include "template.h"
using namespace std;

int main()
{
	TC3<int> tint3;
	tint3.funtest();
	TC3<int&> tint3_ref;
	tint3_ref.funtest();
	TC3<int*> tint3_point;
	tint3_point.funtest();
	TC3<const int> tint3_const;
	tint3_const.funtest();
}

运行结果截图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值