模板类的写法

模板类的核心就是:把类里的数据类型参数化 ,让同一个类能处理 int、double、string 等各种类型。

基本写法

cpp 复制代码
1template <typename T>   // 声明模板参数 T
2class Stack {
3public:
4    Stack(int capacity = 4)
5        : _array(new T[capacity])
6        , _top(0)
7        , _capacity(capacity)
8    {}
9
10    ~Stack() {
11        delete[] _array;
12    }
13
14    void Push(const T& x) {
15        _array[_top++] = x;
16    }
17
18    T Top() const {
19        return _array[_top - 1];
20    }
21
22private:
23    T* _array;
24    int _top;
25    int _capacity;
26};

使用时:

cpp 复制代码
1Stack<int> s1;          // int 版本的栈
2Stack<double> s2;       // double 版本的栈
3Stack<std::string> s3;  // string 版本的栈

成员函数在类外定义

模板类的成员函数如果在类外定义,每个函数前面都要加 template<typename T>:

cpp 复制代码
1template <typename T>
2void Stack<T>::Push(const T& x) {
3    _array[_top++] = x;
4}
5
6template <typename T>
7T Stack<T>::Top() const {
8    return _array[_top - 1];
9}

注意类名要写成 Stack<T>,不能只写 Stack。

多个模板参数

cpp 复制代码
1template <typename K, typename V>
2class HashMap {
3    // ...
4};
5
6HashMap<std::string, int> map;

模板参数也可以是非类型参数

cpp 复制代码
1template <typename T, int N>
2class Array {
3    T _data[N];  // N 是编译期常量
4};
5
6Array<int, 10> arr;  // 大小为 10 的 int 数组

关键特性

  • 模板不是类 ,它只是一个"蓝图"。只有当你写 Stack<int> 时,编译器才会根据模板实例化 出一个真正的 Stack<int> 类。
  • 模板的定义(声明+实现)通常要放在头文件(.h/.hpp) 里,不能像普通类那样把声明放 .h、定义放 .cpp,否则链接时会报错(因为编译器在别的翻译单元看不到模板定义,无法实例化)。
  • typename 和 class 在这里等价,但习惯上类型参数用 typename,模板模板参数用 class。

拓展

类名<T> vs 类名

场景 写法 示例
使用模板类(实例化) 必须写 <T> Stack<int> s;
类内写成员函数 直接写类名 void Push(const T& x);
类外定义成员函数 必须写 Stack<T>:: void Stack<T>::Push(...)
模板类内部引用自身 可以只写类名 Stack* _next;
友元、继承、typedef 通常需要 <T> friend class Iterator<T>;

本质理解

Stack 不是类,它只是一个模板。

Stack<int>、Stack<double> 才是真正的类(编译器根据模板实例化出来的)。

所以:

cpp 复制代码
1template <typename T>
2class Stack {
3public:
4    void Push(const T& x);  // 类内,直接写类名就行
5};
6
7// 类外定义,必须带 <T>
8template <typename T>
9void Stack<T>::Push(const T& x) { ... }
10//     ^^^^^^^^ 这里必须写 Stack<T>
11
12// 使用时,必须带 <T>
13Stack<int> s;        // ✅
14Stack s;             // ❌ 编译报错,Stack 不是类

C++17 的例外:类模板参数推导(CTAD)

从 C++17 开始,如果你提供了构造函数,编译器可以自动推导类型:

cpp 复制代码
1template <typename T>
2class Stack {
3public:
4    Stack(const T& val) { ... }
5};
6
7Stack s(42);  // ✅ C++17 起合法,自动推导为 Stack<int>

但这只是语法糖,底层还是 Stack<int>。

简单记:只要你在"使用"一个模板类,就必须带上 <类型>;只有在模板类自己的定义内部,才可以省略。

相关推荐
帷幕落秋1 小时前
经典命令场景与软硬链接
linux·运维
CCCCCCCCharlie2 小时前
深入解析I/O底层:文件描述符与缓冲区真相
linux·开发语言·c++·算法
自信150413057592 小时前
重生之从0开始学习c++之string(下)
c++·学习·stl
kmomo..2 小时前
Linux 驱动开发学习笔记:UART、触摸屏与 ADC 驱动实战
linux·驱动开发·学习
先知后行。2 小时前
各种文件系统
linux·服务器·数据库
人工智能培训2 小时前
具身智能环境交互与学习范式原理
大数据·linux·人工智能·学习·算法·机器学习
Sayai3 小时前
Java 进程 Unable to create new native thread 排查实战:Linux 线程数五层限制与 JVM -Xss 调优
java·linux·运维·jvm·性能优化
CS_Zero3 小时前
解决模型开发板ping不通模型终端设备问题
linux·网络
wuminyu3 小时前
Continuation::freeze与thaw的x86_64汇编Stack Chunk拆解源码分析
java·linux·c语言·汇编·jvm·c++