6.6 类模板

 

6.6 类模板

类模板是C++语言支持参数化的一种工具,旨在实现代码重用,使代码能够适应不同的数据类型和操作。类模板允许我们定义具有某些数据成员和成员函数的类,这些数据成员和成员函数可以使用多种类型,从而提高代码的通用性和重用性。

6.6.1 类模板的引入

引入类模板的目的是为了更好地进行代码重用,避免为每种数据类型重复编写相同的代码。类模板允许我们创建一个通用的类,这个类可以处理不同类型的数据。下面通过一个链表类的例子来说明类模板的必要性。

示例:链表类

非模板实现
class Node {
    // 结点类的定义
};

class List {
public:
    List();
    ~List();
    void Add(Node &);
    void Remove(Node &);
    Node* Find(Node &);
};

这个链表类只能处理Node类型的结点。如果我们需要处理其他类型的结点,就需要重新定义链表类,这会导致代码的重复和维护的复杂性。

使用模板实现

通过引入类模板,可以使链表类通用化:

template <typename T>
class List {
public:
    List();
    ~List();
    void Add(T &);
    void Remove(T &);
    T* Find(T &);
};

在这个类模板中,使用了一个参数化的类型T,它被用作成员函数参数的类型。这样,链表类可以处理任何类型的结点,显著提高了代码的重用性和灵活性。

6.6.2 类模板和模板类

类模板的定义格式

类模板的定义格式如下:

template <typename T>
class 类名 {
    // 类体
};

template关键字用于定义类模板,<typename T>表示模板参数。模板参数可以有多个,用逗号分隔。

示例:有界数组的类模板

template <typename AType>
class Array {
public:
    Array(int size);
    ~Array() { delete[] a; }
    AType& operator[](int i);
private:
    int length;
    AType* a;
};

template <typename AType>
Array<AType>::Array(int size) {
    length = size;
    a = new AType[size];
    for (int i = 0; i < size; i++) {
        a[i] = 0;
    }
}

template <typename AType>
AType& Array<AType>::operator[](int i) {
    if (i < 0 || i >= length) {
        std::cerr << "Index out-of-bounds.\n";
        exit(1);
    }
    return a[i];
}

定义类模板时需要注意以下几点:

  1. 使用template关键字。
  2. 确定至少一个模板参数,多个模板参数用逗号分隔。
  3. 类模板中的成员函数可以是函数模板。

模板类

在定义了类模板之后,系统会根据需要生成相应的模板类。例如,使用Array<int>Array<double>分别生成int型和double型的模板类。

示例:使用模板类

#include <iostream>
#include "Array.h"

int main() {
    Array<int> intArray(10);
    Array<double> doubleArray(5);

    for (int i = 0; i < 10; i++) {
        intArray[i] = i + 1;
    }

    for (int i = 0; i < 5; i++) {
        doubleArray[i] = (i + 1) * 3.14;
    }

    std::cout << "Integer array: ";
    for (int i = 0; i < 10; i++) {
        std::cout << intArray[i] << " ";
    }
    std::cout << std::endl;

    std::cout << "Double array: ";
    for (int i = 0; i < 5; i++) {
        std::cout << doubleArray[i] << " ";
    }
    std::cout << std::endl;

    return 0;
}

通过使用类模板,可以创建适用于不同数据类型的数组,并对其进行操作。

6.6.3 类模板应用举例

类模板在实际编程中应用广泛,可以显著提高代码的重用性。下面是一个栈的类模板的示例。

示例:栈的类模板

#include <iostream>
#include <cstdlib>

template <typename T>
class Stack {
public:
    Stack(int size);
    ~Stack() { delete[] stack; }
    void push(T i);
    T pop();
private:
    int tos;
    int length;
    T* stack;
};

template <typename T>
Stack<T>::Stack(int size) {
    stack = new T[size];
    if (!stack) {
        std::cerr << "Cannot allocate stack.\n";
        exit(1);
    }
    length = size;
    tos = 0;
}

template <typename T>
void Stack<T>::push(T i) {
    if (tos == length) {
        std::cerr << "Stack is full.\n";
        return;
    }
    stack[tos++] = i;
}

template <typename T>
T Stack<T>::pop() {
    if (tos == 0) {
        std::cerr << "Stack underflow.\n";
        exit(1);
    }
    return stack[--tos];
}

int main() {
    Stack<int> intStack(10);
    Stack<double> doubleStack(10);
    Stack<char> charStack(10);

    intStack.push(15);
    doubleStack.push(18.1);
    intStack.push(18);
    intStack.push(14);
    doubleStack.push(3.14);

    std::cout << intStack.pop() << ", ";
    std::cout << intStack.pop() << ", ";
    std::cout << intStack.pop() << std::endl;
    std::cout << doubleStack.pop() << ", ";
    std::cout << doubleStack.pop() << std::endl;

    for (int i = 0; i < 10; i++) {
        charStack.push('A' + i);
    }
    for (int i = 0; i < 10; i++) {
        std::cout << charStack.pop();
    }
    std::cout << std::endl;

    return 0;
}

执行该程序,输出结果如下:

14, 18, 15
3.14, 18.1
JIHGFEDCBA

这个例子展示了如何使用类模板来创建和操作不同类型的栈,提高了代码的重用性和灵活性。

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏驰和徐策

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值