C++ 知识点23 类模板

C++ 类模板


一、为什么要有类模板?

比如要写栈、数组、链表容器:

你需要 int 栈、double 栈、string 栈......

如果不写模板,要重复写多份几乎一样的类,代码极度冗余。

类模板作用 :用一套类模板骨架 ,支持任意数据类型,编译器根据类型自动生成对应具体类

函数模板:通用函数

类模板:通用类


二、类模板 基础语法格式

1. 标准头

cpp 复制代码
template<typename T>
// 或 template<class T> 效果完全一样
class 类名
{
    // 成员变量、成员函数都可以用 T 做类型
private:
    T val;
public:
    void setVal(T v);
    T getVal();
};
  • template<typename T>:声明模板参数

  • T:类型占位符,代表任意类型

  • 类里所有成员都可以直接用 T

2. 最简完整示例

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;
​
// 定义类模板
template<typename T>
class Person
{
private:
    T age;
public:
    void setAge(T a)
    {
        age = a;
    }
    T getAge()
    {
        return age;
    }
};
​
int main()
{
    // 类模板 必须显式指定类型,不能自动推导
    Person<int> p1;
    p1.setAge(20);
    cout << p1.getAge() << endl;
​
    Person<double> p2;
    p2.setAge(20.5);
    cout << p2.getAge() << endl;
​
    return 0;
}

关键区别(和函数模板)

函数模板可以自动类型推导;类模板不能自动推导,必须尖括号指定类型 <类型>


三、类模板 成员函数 类外实现(重点必考)

模板类的成员函数写在类外面,格式固定套路:

cpp 复制代码
// 1. 先写模板头
template<typename T>
// 2. 类名<T> 指明作用域
void Person<T>::setAge(T a)
{
    age = a;
}
​
template<typename T>
T Person<T>::getAge()
{
    return age;
}

固定格式口诀

cpp 复制代码
template<typename T>
返回值 类名<T>::函数名(参数)

完整可直接复制代码:

cpp 复制代码
#include <iostream>
using namespace std;
​
template<typename T>
class Person
{
private:
    T age;
public:
    void setAge(T a);
    T getAge();
};
​
// 类外实现
template<typename T>
void Person<T>::setAge(T a)
{
    age = a;
}
​
template<typename T>
T Person<T>::getAge()
{
    return age;
}
​
int main()
{
    Person<int> p;
    p.setAge(18);
    cout << p.getAge() << endl;
    return 0;
}

四、类模板 多个模板参数

可以同时定义多个类型参数 T1, T2

cpp 复制代码
template<typename T1, typename T2>
class Pair
{
private:
    T1 first;
    T2 second;
public:
    void set(T1 a, T2 b)
    {
        first = a;
        second = b;
    }
    void show()
    {
        cout << first << " " << second << endl;
    }
};
​
int main()
{
    Pair<int, string> p;
    p.set(100, "DYKP");
    p.show();
    return 0;
}

五、类模板 模板参数可以带默认类型

给模板参数设置默认类型,不指定就用默认:

cpp 复制代码
// 默认 T 为 int
template<typename T = int>
class Array
{
private:
    T arr[10];
};
​
int main()
{
    Array<> a1;      // 不写类型,用默认 int
    Array<double> a2;// 手动指定 double
    return 0;
}

六、类模板的实例化原理

  1. 类模板本身不是类,只是一张模板图纸;

  2. 当你写 Person<int>Person<double> 时,编译器才会生成对应的具体类

  3. 每一种类型,都会产生一份独立的类代码;

  4. 没有使用的类型,不会生成代码,不占空间。


七、类模板特化(重点难点)

1. 全局特化(全类特化)

通用模板对某一个类型单独重写一整套类

cpp 复制代码
// 通用类模板
template<typename T>
class Data
{
public:
    void print()
    {
        cout << "通用版本" << endl;
    }
};
​
// 针对 string 类型 全特化
template<>
class Data<string>
{
public:
    void print()
    {
        cout << "string 特化版本" << endl;
    }
};

使用时:

  • Data<int> 走通用模板

  • Data<string> 走特化版本

2. 局部特化(了解)

多个模板参数时,可以只特化其中一部分,考试一般考全特化即可。


八、类模板 作函数参数怎么传

模板类对象作为函数形参,两种写法:

写法 1:函数模板接收模板类

cpp 复制代码
template<typename T>
void showPerson(Person<T> p)
{
    cout << p.getAge() << endl;
}

写法 2:指定固定类型

cpp 复制代码
void showIntPerson(Person<int> p)
{
    cout << p.getAge() << endl;
}

九、类模板 常见易错坑(必记)

  1. 类模板不能自动推导 ,必须 类名<类型>

  2. 类外实现成员函数,必须加 template<T> + 类名<T>::

  3. 模板类

    声明和实现不能拆分到 .h 和 .cpp

    编译需要看到完整模板代码,否则无法实例化,一般全部写在头文件。

  4. 模板里面不能使用不支持该类型的运算(如 T 是 string 却用 ++)

  5. 特化版本必须和通用模板同名,格式不能错。


十、函数模板 vs 类模板 核心对比(面试必背)

对比 函数模板 类模板
语法 template<T> 修饰函数 template<T> 修饰类
推导 可自动类型推导 不能自动推导,必须指定<T>
实例化 调用时生成函数 指定类型时生成类
特化 支持函数特化 支持类全特化、局部特化
外部实现 普通写法 必须带 类名<T>::

十一、极简背诵总结

  1. 类模板用 template<typename T> 定义,是通用类图纸;

  2. 使用必须 类名<类型>无自动推导

  3. 类外写成员函数:必须重写模板头 + 类名<T>::

  4. 支持多模板参数、默认类型参数;

  5. 特化可以给指定类型单独定制整个类;

  6. 模板代码不能分离头文件与源文件;

  7. 原理:用什么类型,编译器才生成对应具体类。

相关推荐
邪修king1 小时前
C++ 继承超全详解:核心语法、作用域、默认函数、菱形继承与避坑指南
c语言·c++
xlq223221 小时前
53.tcp socket
linux·服务器·开发语言·网络·网络协议·tcp/ip
L_09071 小时前
【C++】STL— 封装红黑树以实现map 和 set
数据结构·c++
Royzst1 小时前
Lambda 算法基础 集合概述
java·开发语言
麦兜和小可的舅舅1 小时前
ClickHouse Dist表的Replica选择逻辑深度解析-- Custom Key以及Sample的执行逻辑
c++·clickhouse·distribute·shard
SmallBambooCode1 小时前
【人工智能】【Python】离线环境下huggingface预训练权重导入流程
开发语言·人工智能·python
djarmy1 小时前
C 标准库 `<stdio.h>` 完整函数清单(官方标准 + 常用全部函数)
c语言·c++·算法
code_whiter1 小时前
C++10(list)
c++·windows·list