跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

掌握 C++ 模板与内存管理,消除代码冗余与内存泄漏

C++ 模板技术通过泛型编程解决同逻辑不同类型的代码冗余问题。函数模板允许编译器根据实参类型自动推导生成具体函数版本,支持隐式和显式实例化两种模式。类模板用于定义通用数据结构如栈,需显式指定类型参数。结合 new/delete 底层内存管理机制,掌握模板能有效提升代码复用性与维护性,避免重复编写相似逻辑,是 C++ 进阶的关键技能。

云间运维发布于 2026/3/25更新于 2026/10/2686 浏览
掌握 C++ 模板与内存管理,消除代码冗余与内存泄漏

模板

交换函数

实现通用的交换函数。

void Swap(int& left, int& right) {
    int temp = left;
    left = right;
    right = temp;
}

void Swap(double& left, double& right) {
    double temp = left;
    left = right;
    right = temp;
}

void Swap(char& left, char& right) {
    char temp = left;
    left = right;
    right = temp;
}

缺点

  1. 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增加对应的函数。
  2. 代码的可维护性比较低,一个出错可能所有的重载均出错。

定义

模板是一个'代码蓝图',可以根据传入的类型'生成'对应版本的具体代码。

核心价值

解决'同逻辑、不同类型'的代码冗余问题。

分类

函数模板

定义

定义一个通用函数,参数类型通过模板参数指定,编译器会根据传入的实参类型自动生成对应版本的函数。

格式

template<typename T>

使用 template 和 typename 来声明模板,这里的 typename 也可以使用 class 来代替,不可以使用 struct。T 是参数类型,可以是内置类型或者自定义类型,可以作为函数的参数或者返回值。

多个类型

template<typename T1, typename T2>

代码示例

#include <iostream>
using namespace std;

template<typename T> // T 是模板参数,类似于形参,定义的是类型
void Swap(T& x1, T& x2) {
    T tmp = x1;
    x1 = x2;
    x2 = tmp;
}

int main() {
    int a = 0, b = 1;
    double c = 1.1, d = 2.2;
    Swap(a, b);
    cout << a << " " << b << endl;
    Swap(c, d);
    cout << c << " " << d << endl;
    return 0;
}

上面的代码中,2 个 Swap 调用的不是同一个函数,编译器通过类型自动推导出函数。

函数模板的原理

编译器根据参数类型推导出具体函数。

可以直接使用库里面的 swap 模板,库里面的 swap 是小写。

#include <iostream>
using namespace std;

int main() {
    int a = 1, b = 2;
    cout << a << " " << b << endl;
    swap(a, b);
    cout << a << " " << b << endl;
    return 0;
}

函数模板的实例化

隐式实例化

编译器根据实参推演模板参数的实际类型。

#include <iostream>
using namespace std;

template<class T>
T Add(const T& left, const T& right) {
    return left + right;
}

int main() {
    int a1 = 10, a2 = 20;
    double d1 = 10.1, d2 = 20.2;
    cout << Add(a1, d1) << endl;
    return 0;
}

代码报错是因为 a1 和 d1 的类型不同,模板参数列表中只有一个 T,编译器无法确定此处到底该将 T 确定为 int 或者 double 类型而报错,在模板中,编译器一般不会进行类型转换操作。下面有两种解决方法。

方法 1

在参数前面添加强制类型转换。

#include <iostream>
using namespace std;

template<class T>
T Add(const T& left, const T& right) {
    return left + right;
}

int main() {
    int a1 = 10, a2 = 20;
    double d1 = 10.1, d2 = 20.2;
    cout << Add(a1, (int)d1) << endl;
    cout << Add((double)a1, d1) << endl;
    return 0;
}

不同的强制类型转换,得到的结果是不一样的。

方法 2

显示类型转换,在函数名后的 <> 中指定模板参数的实际类型。

#include <iostream>
using namespace std;

template<class T>
T Add(const T& left, const T& right) {
    return left + right;
}

int main() {
    int a1 = 10, a2 = 20;
    double d1 = 10.1, d2 = 20.2;
    // cout << Add(a1, a2) << endl;
    // cout << Add(d1, d2) << endl;
    // 强制类型转换
    // cout << Add(a1, (int)d1) << endl;
    // cout << Add((double)a1, d1) << endl;
    // 显示实例化
    cout << Add<int>(a1, d2) << endl;
    // 隐式类型转换
    cout << Add<double>(a1, d2) << endl;
    return 0;
}

Add 函数中,使用 const 是因为隐式类型转换会产生临时变量,临时变量具有常性。

特殊情况

有些函数无法自动推导,只能显示实例化。

#include <iostream>
using namespace std;

template<typename T>
T* Alloc(int n) {
    return new T[n];
}

int main() {
    double* p1 = Alloc<double>(10);
    return 0;
}

泛型编程

使用模板来完成的,代码针对广泛的类型。

类模板

格式

template<class T1, class T2, ..., class Tn>
class 类模板名 {
    // 类内成员定义
};

类模板可以定义多个模版参数。

代码示例

类模板只能显示实例化,不能传递参数。

#include <iostream>
using namespace std;

template<typename T>
class Stack {
public:
    Stack(size_t capacity = 3) {
        cout << "Stack(size_t capacity = 3)" << endl;
        _array = new T[capacity]; // 只需要个数
        _capacity = capacity;
        _size = 0;
    }

    void Push(const T& data) {
        _array[_size] = data;
        _size++;
    }

    ~Stack() {
        cout << "~Stack()" << endl;
        if (_array) {
            delete[] _array;
            _array = NULL;
            _capacity = 0;
            _size = 0;
        }
    }

private:
    T* _array;
    int _capacity;
    int _size;
};

int main() {
    Stack<int> s1;
    // Stack<double> s1;
    return 0;
}

类模板的实例化

类模板实例化与函数模板实例化不同,类模板实例化需要在类模板名字后跟 <>,然后将实例化的类型放在 <> 中即可,类模板名字不是真正的类,而实例化的结果才是真正的类。

普通类,类名和类型一样,类模板,类名和类型不一样。例如:类名:Stack,类型:Stack。

template< typename T > 的作用范围是下一个函数或者类。

总结

模板的出现,让 C++ 代码摆脱了重复冗余的枷锁,无论是函数模板实现通用逻辑复用,还是类模板构建灵活数据结构,都极大提升了编程效率与代码可维护性。掌握这些知识,就像拿到了 C++ 进阶的密钥,助力我们写出更简洁、更高效、更具扩展性的代码,在编程之路上走得更远、更稳,去探索更广阔的代码天地。

目录

  1. 模板
  2. 交换函数
  3. 定义
  4. 核心价值
  5. 分类
  6. 函数模板
  7. 定义
  8. 格式
  9. 代码示例
  10. 函数模板的原理
  11. 函数模板的实例化
  12. 泛型编程
  13. 类模板
  14. 格式
  15. 代码示例
  16. 类模板的实例化
  17. 总结

更多推荐文章

查看全部
  • HarmonyOS 6.0 使用 PAC 脚本灵活管理网络连接
  • 网络安全工程师入门指南:三年经验总结与学习路径
  • OpenClaw 汉化版部署与常见问题排查指南
  • 攻防世界 Web 题解 (八): 加密解密、反序列化、RCE 及文件包含
  • Flutter 三方库 huggingface_client 的鸿蒙化适配指南
  • JavaScript 宏任务与微任务详解
  • 缓存算法 LRU 与 LFU 详解
  • 联邦学习架构解析:多医院协作训练 AI 模型方案
  • 县域烟花禁燃监管 GIS 实践:Java 调用高德地图 API 盘点销售点
  • 即梦 AI 基础操作指南:绘画与视频生成
  • 构建与 GitHub 深度集成的自动化工作流指南
  • Java 后端实习复盘:企业级项目实战与代码规范分享
  • Web 团队开发 App 是否应选用 Capacitor
  • NativeScript-Vue 跨平台原生应用开发实战
  • Python 循环语句详解:For 与 While 用法及控制流程
  • 大模型智能体(Agent)核心概念与架构解析
  • Java 基础核心知识点总结:深拷贝、泛型、对象与反射
  • Hymba:融合注意力与 SSM 头的新型语言模型架构
  • VisionTransformer(ViT)在时间序列行为识别中的应用
  • ComfyUI 扩展 WAS Node Suite 安装与功能指南

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online