首页
社区
课程
招聘
[分享]C++基础十六-模板
发表于: 2021-10-26 17:53 8939

[分享]C++基础十六-模板

2021-10-26 17:53
8939

泛型程序设计是一种算法在实现时不指定具体要操作的数据的类型的程序设计方法,能够减少重复代码的编写。所谓泛型,指的是算法只要实现一遍,就能适用于多种数据类型。

C++ 中数据的值可以通过函数参数传递,在函数定义时数据的值是未知的,只有等到函数调用时接收了实参才能确定其值。这就是值的参数化。同理,数据的类型也可以通过参数来传递,在函数定义时可以不指明具体的数据类型,当发生函数调用时,编译器可以根据传入的实参自动推断数据类型。这就是类型的参数化。
所谓函数模板,实际上是建立一个通用函数,它所用到的数据的类型(包括返回值类型、形参类型、局部变量类型)可以不具体指定,而是用一个虚拟的类型来代替(实际上是用一个标识符来占位),等发生函数调用时再根据传入的实参来逆推出真正的类型。这个通用函数就称为函数模板。
为了交换不同类型的变量的值,可以通过函数重载定义名字相同、参数列表不同的函数,但从本质上看还是定义了功能相同、函数体相同的函数,只是数据的类型不同。通过函数模板,可以实现一个函数解决问题。

template是定义函数模板的关键字,它后面紧跟尖括号<>,尖括号包围的是类型参数,typename是用来声明具体的类型参数的关键字,这里的类型参数就是T。从整体上看,template<typename T>被称为模板头,模板头中包含的类型参数可以用在函数定义的各个位置,包括返回值、形参列表和函数体。

C++ 还支持类模板,类模板的目的同样是将数据的类型参数化。函数模板中定义的类型参数可以用在函数声明和函数定义中,类模板中定义的类型参数可以用在类声明和类实现中。

类模板和函数模板都是以template 开头,后跟类型参数,类型参数不能为空,多个类型参数用逗号隔开。一但声明了类模板,就可以将类型参数用于类的成员函数和成员变量了。

#include <iostream>
using namespace std;
 
template<typename T> void Swap(T& NumberA, T& NumberB)
{
    T temp = NumberA;
    NumberA = NumberB;
    NumberB = temp;
}
 
int main()
{
    //交换 int 变量的值
    int n1 = 8;
    int n2 = 9;
    Swap(n1, n2);
    cout << "n1=" << n1 << " n2=" << n2 << endl;
 
    //交换 float 变量的值
    float f1 = 8.8;
    float f2 = 9.9;
    Swap(f1, f2);
    cout << "f1=" << f1 << " f2=" << f2 << endl;
 
    return 0;
}
#include <iostream>
using namespace std;
 
template<typename T> void Swap(T& NumberA, T& NumberB)
{
    T temp = NumberA;
    NumberA = NumberB;
    NumberB = temp;
}
 
int main()
{
    //交换 int 变量的值
    int n1 = 8;
    int n2 = 9;
    Swap(n1, n2);
    cout << "n1=" << n1 << " n2=" << n2 << endl;
 
    //交换 float 变量的值
    float f1 = 8.8;
    float f2 = 9.9;
    Swap(f1, f2);
    cout << "f1=" << f1 << " f2=" << f2 << endl;
 
    return 0;
}
template<typename 类型参数1,typename 类型参数2,...> class 类名
{
    //TODO:
};
template<typename 类型参数1,typename 类型参数2,...> class 类名
{
    //TODO:
};
#include <iostream>
using namespace std;
 
template<typename T> void Swap(T& NumberA, T& NumberB)
{
    T temp = NumberA;
    NumberA = NumberB;
    NumberB = temp;
}
 
template <typename T> class CArray
{
    int size; //数组元素的个数
    T* ptr; //指向动态分配的数组
public:
    CArray(int s = 0);  //s代表数组元素的个数
    CArray(CArray& a);
    ~CArray();
    T length();
    T& operator[](int i); //用以支持根据下标访问数组元素
    CArray& operator=(const CArray& a); //用于数组对象间的赋值
    void push_back(const T& v); //用于在数组尾部添加一个元素v
};
 
template<typename T>
T CArray<T>::length()
{
    return size;
}
 
template<typename T>
T& CArray<T>::operator[](int i)
{
    return ptr[i];
}
 
template<class T>
CArray<T>::CArray(int s) :size(s)
{
    if (s == 0)
    {
        ptr = NULL;
    }
    else
    {
        ptr = new T[s];
    }
}
 
template<class T>
CArray<T>::CArray(CArray& a)
{
    if (!a.ptr)
    {
        ptr = NULL;
        size = 0;
        return;
    }
    ptr = new T[a.size];
    memcpy(ptr, a.ptr, sizeof(T) * a.size);
    size = a.size;
}
 
template <class T>
CArray<T>::~CArray()
{
    if (ptr)
    {
        delete[] ptr;
    }
    size = 0;
}
 
template <class T>
CArray<T>& CArray<T>::operator=(const CArray& a)
{
    if (this == &a)
    {
        return *this;
    }
    if (a.ptr == NULL)
    {
        if (ptr)
        {
            delete[] ptr;
        }
        ptr = NULL;
        size = 0;
        return *this;
    }
    if (size < a.size)
    {
        if (ptr)
        {
            delete[] ptr;
        }
        ptr = new T[a.size];
    }
    memcpy(ptr, a.ptr, sizeof(T) * a.size);
    size = a.size;
    return *this;
}
 
template <class T>
void CArray<T>::push_back(const T& v)
{
    if (ptr)
    {
        T* tmpPtr = new T[size + 1]; //重新分配空间
        memcpy(tmpPtr, ptr, sizeof(T) * size); //拷贝原数组内容
        delete[] ptr;
        ptr = tmpPtr;
    }
    else
    {
        ptr = new T[1];
    }
    ptr[size++] = v;
}
 
int main()
{
    //交换 int 变量的值
    int n1 = 8;
    int n2 = 9;
    Swap(n1, n2);
    cout << "n1=" << n1 << " n2=" << n2 << endl;
 
    //交换 float 变量的值
    float f1 = 8.8;
    float f2 = 9.9;
    Swap(f1, f2);
    cout << "f1=" << f1 << " f2=" << f2 << endl;
 
    CArray<int> a;
    for (int i = 0; i < 6; ++i)
    {
        a.push_back(i);
    }
    for (int i = 0; i < a.length(); ++i)
    {
        cout << a[i] << " ";
    }
 
    return 0;
}
#include <iostream>
using namespace std;
 
template<typename T> void Swap(T& NumberA, T& NumberB)
{
    T temp = NumberA;
    NumberA = NumberB;
    NumberB = temp;
}
 
template <typename T> class CArray
{
    int size; //数组元素的个数
    T* ptr; //指向动态分配的数组
public:
    CArray(int s = 0);  //s代表数组元素的个数
    CArray(CArray& a);
    ~CArray();
    T length();
    T& operator[](int i); //用以支持根据下标访问数组元素
    CArray& operator=(const CArray& a); //用于数组对象间的赋值
    void push_back(const T& v); //用于在数组尾部添加一个元素v
};
 
template<typename T>
T CArray<T>::length()
{
    return size;
}
 
template<typename T>
T& CArray<T>::operator[](int i)
{
    return ptr[i];
}
 
template<class T>
CArray<T>::CArray(int s) :size(s)
{
    if (s == 0)
    {
        ptr = NULL;
    }
    else
    {
        ptr = new T[s];
    }
}
 
template<class T>
CArray<T>::CArray(CArray& a)
{
    if (!a.ptr)
    {
        ptr = NULL;
        size = 0;

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//