专业编程基础技术教程

网站首页 > 基础教程 正文

【C++泛型编程】(一)函数模板和类模板

ccvgpt 2024-08-03 12:31:31 基础教程 12 ℃

(一)函数模板和类模板

C++泛型编程(Generic Programming)是一种编程范式,它允许程序员编写与参数无关的代码,也就是说这些代码可以在多种数据类型上重用,而无需为每个类型重新编写。

泛型编程的主要工具是模板(Templates),主要分为两种类型:函数模板和类模板。

【C++泛型编程】(一)函数模板和类模板

函数模板

函数模板允许程序员编写一个通用的函数,该函数可以接受不同类型的参数,并在编译时根据提供的参数类型生成特定的函数版本。其语法如下:

template<typename T>
return_type functionName(T arg1, T arg2) {
    // 函数体
}
  • template --- 声明创建模板
  • typename --- 表面其后面的符号是一种数据类型,可以用class代替
  • T --- 通用的数据类型。T只是一个约定的名称,可以将其改为其他标识符。
  • return_type : 返回值的类型,需要根据函数体指定,如:voidint或者T

函数模板的实例化

在使用函数模板时,编译器会根据传递的参数类型自动推导模板参数:

functionName(arg1, arg2); // 自动推导

或者你可以显式指定模板参数:

functionName<int>(arg1, arg2); // 显式实例化

示例:返回两个数中的较大者

#include <iostream>

// 函数模板:返回两个数中的较大者
template<typename T>
T max(T a, T b) {
    return (a > b) ? a : b;
}

int main() {
    std::cout << "Max of 5 and 3: " << max(5, 3) << std::endl;// 调用max<int>(5, 10)
    std::cout << "Max of 5.5 and 3.3: " << max(5.5, 3.3) << std::endl;// 调用max<double>(5.5, 3.3)
    return 0;
}
Max of 5 and 3: 5
Max of 5.5 and 3.3: 5.5

类模板

类模板则允许你编写一个通用的类,该类可以在编译时根据提供的类型参数生成特定的类版本。基本语法:

template<typename T>
// 类

类模板的定义包括构造函数、成员函数和成员变量等的定义,模板参数在类内部可以用作类型标识符:

template<typename T>
class ClassName {
public:
    ClassName(T value); // 构造函数模板
    void setValue(T value); // 成员函数模板

private:
    T data; // 数据成员
};

// 类模板的析构函数、构造函数和成员函数的实现通常放在类模板定义的外部。
template<typename T>
ClassName<T>::ClassName(T value) : data(value) {}

template<typename T>
void ClassName<T>::setValue(T value) {
    data = value;
}

类模板的实例化

在使用类模板时,需要为模板参数指定具体的类型。

ClassName<int> obj(42);

示例:一个通用数据类型的栈数据结构

#include <iostream>
// 类模板:一个简单的栈
template<typename T>
class Stack {
public:
    Stack();
    ~Stack(); 
    void push(T value);
    T pop();

private:
    T* data;
    int top;
    const static int size = 100;
};
// 类模板的构造函数
template<typename T>
Stack<T>::Stack() {
    data = new T[size];
    top = -1;
}
// 类模板的析构函数 
template<typename T>  
Stack<T>::~Stack() {  
    delete[] data; // 释放动态分配的数组  
}  
// 类模板的成员函数:入栈
template<typename T>
void Stack<T>::push(T value) {
    data[++top] = value;
}
// 类模板的成员函数:出栈
template<typename T>
T Stack<T>::pop() {
    return data[top--];
}

int main() {
    Stack<int> intStack;
    intStack.push(1);
    intStack.push(2);
    intStack.push(3);
    std::cout << intStack.pop() << std::endl; // 输出3
    std::cout << intStack.pop() << std::endl; // 输出2
    return 0;
}

模板的特化

模板的特化(Template Specialization)是一种对通用模板进行特殊处理的技术,以适应特定类型或条件的需求,可以分为全特化和偏特化两种类型:

  • 全特化:全特化是指对模板的所有模板参数都进行特化处理。例如,如果有一个模板类Test<T1, T2>,全特化可能是为Test<int, char>这样的具体类型提供特定的实现。
  • 偏特化:偏特化是指只对部分模板参数进行特化处理。例如,如果有一个模板类Test<T1, T2>,偏特化可能是为Test<T1, char>这样的部分具体类型提供特定的实现,其中T1仍然是一个模板参数。

示例:

#include <iostream>

// 通用模板类定义
template<typename T1, typename T2>
class Test {
public:
    void show() {
        std::cout << "General template" << std::endl;
    }
};

// 全特化示例:为Test<int, char>提供特定实现
template<>
class Test<int, char> {
public:
    void show() {
        std::cout << "Full specialization for Test<int, char>" << std::endl;
    }
};

// 偏特化示例:为Test<T1, char>提供特定实现,其中T1是任意类型
template<typename T1>
class Test<T1, char> {
public:
    void show() {
        std::cout << "Partial specialization for Test<T1, char>" << std::endl;
    }
};

int main() {
    // 使用通用模板类
    Test<double, double> t1;
    t1.show(); // 输出:General template

    // 使用全特化类
    Test<int, char> t2;
    t2.show(); // 输出:Full specialization for Test<int, char>

    // 使用偏特化类
    Test<float, char> t3;
    t3.show(); // 输出:Partial specialization for Test<T1, char>

    return 0;
}

对于函数模板,一般采用重载(Overloading)代替特化。例如,如果你有一个函数模板,并且想要为int类型提供特定的实现,你可以简单地重载该函数模板:

#include <iostream>

// 通用函数模板
template<typename T>
void print(T value) {
    std::cout << "Generic print: " << value << std::endl;
}

// 重载函数模板,为int类型提供特定实现
void print(int value) {
    std::cout << "Specialized print for int: " << value << std::endl;
}

int main() {
    print(10);     // 调用重载版本,输出 "Specialized print for int: 10"
    print(3.14);   // 调用通用模板版本,输出 "Generic print: 3.14"
    print("Hello"); // 调用通用模板版本,输出 "Generic print: Hello"
    return 0;
}

Tags:

最近发表
标签列表