当前位置: 首页 > news >正文

C++入门自学Day6-- C++模版

  往期内容回顾     

           C/C++内存管理(初识)

            C/C++内存管理(续)

一、泛型编程

1、什么是泛型编程(Generic Programming)

泛型编程 是一种编程范式,其核心思想是:

编写独立于数据类型的算法或数据结构,使其可以应用于多个类型之上。

换句话说,不管你是对 int、double、string 还是自定义类型操作,都可以使用同一个函数或类模板

二、C++ 模板介绍

        C++ 提供了两种模板:

1. 函数模板(Function Template)

定义格式:
template<typename T>
T Max(T a, T b) {return a > b ? a : b;
}

举个例子:


template<typename T>
void Swap(T& a,T& b){T tmp = a;a = b;b =tmp;
};int main(){double a = 12.1;double b = 2;Swap(a,b);cout<<"a = "<<a<<" b = "<<b<<endl;
}

注意:调用函数模版实例化生成的对应类型的函数,如果T = int则实例化int类型的swap函数。在预处理阶段模版实例化推演成对应类型的函数。


2. 类模板(Class Template)

        定义格式:

利用模版可实例化自定义栈类型,存放整型数据,浮点型的栈。

template<class T>
class Vector{public:Vector():_a(nullptr),_top(0),_capacity(0){};~Vector(){delete[] _a;_top = 0;_capacity =0;};//类内函数声明void push_back(const T& x);void pop_back(); private:T* _a;size_t _top;size_t _capacity;
};
// 类外面定义函数
template<class T>
void push_pop(){
};
void pop_back(){
};
template<typename T>
class Stack {
public:void push(const T& val) { data.push_back(val); }void pop() { data.pop_back(); }T top() const { return data.back(); }bool empty() const { return data.empty(); }
private:std::vector<T> data;
};int main(){Stack<int> s1;
}

3. 模板与泛型编程的关系

模板

泛型编程

是泛型编程在 C++ 中的语言机制

是一种更高层次的思想/设计模式

编译期生成具体类型的代码

设计期考虑如何让算法与类型解耦

C++ 模板实现了泛型编程思想

STL 是泛型编程的典范


4、模板优点与缺点

 优点:
  • 代码复用性高:避免重复编写多份类似函数/类。

  • 类型安全:编译期检查。

  • 性能好:模板代码在编译期展开,不影响运行效率。

缺点:
  • 可读性差:报错信息复杂。

  • 编译时间长:模板实例化多。

  • 代码膨胀:每个类型实例化一次,可能增加编译后的体积。


5、模版总结

项目

内容

本质

模板是编译期的代码生成工具

类型

函数模板、类模板

作用

泛化函数和类,支持多种类型

与泛型编程关系

模板是泛型编程的语言支持,泛型编程是一种设计思想

代表应用

STL(如 vector、map、algorithm 等)


三、模版编程实现顺序表Vector

        1、Vector类的定义

template<class T>
class Vector{public://初始化列表Vector():_top(0),_capacity(10){_a = new T[_capacity];};//析构函数~Vector(){delete[] _a;_top = 0;_capacity =0;};//类内函数声明void push_back(const T& x);void pop_back(); // 运算符重载T& operator[](size_t i){assert(i<_top);return _a[i];}size_t size(){return _top;}private:T* _a;size_t _top;size_t _capacity;
};

2、类外函数定义:

//类外的函数定义
template<class T>
void Vector<T>::push_back(const T& x){//空间不够if(_top == _capacity){size_t new_capacity = 2*_capacity;T* tmp = new T[new_capacity];if(_a){memcpy(tmp,_a,sizeof(T)*_top);delete [] _a;}_a = tmp;_capacity = new_capacity;}else{ _a[_top++] = x;}
};
template<class T>
void Vector<T>::pop_back(){assert(_top>0);_top--;
};

主函数调用:

int main(){Vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);for(int i =0;i<v.size();i++){v[i]*=2;};for(int i =0;i<v.size();i++){cout<<v[i]<<" ";};cout<< endl;}

输出描述:

2 4 6 

、函数模版的实例化

        什么是模板实例化?

        模板实例化(Instantiation)**指的是:编译器根据模板参数类型,生成对应的具体函数或类代码的过程。

隐氏实例化

template<typename T>
T add(T& a,T& b){return a+b;
};

int main(){int a = 1;int b =2;double c = 2.1;double d = 1.2;cout<<"a + b = "<< add(a,b)<<endl;实例化为 int add(int, int)cout<<"c + d = "<< add(c,d)<<endl; 实例化为double add(double, double)
}

输出描述:

a + b = 3
c + d = 3


显式实例化

    // 显示实例化 (指定 T 的类型)cout<<"a + b = "<<add<int>(a,b);

你可以主动告诉编译器实例化某个版本:

template int add<int>(int, int);  // 告诉编译器生成这个版本,无需调用

函数模板是 在使用时才实例化,这意味着:

  • 不使用不会实例化,不会生成代码

  • 必须 模板函数的定义可见,才能实例化成功(通常模板放头文件中)


五、函数模板 vs 普通函数的优先级

        普通函数的优先级 >> 函数模版

void add(int a, int b) {cout << "普通函数" << endl;
}
template <typename T>
T add(T a, T b) {cout << "模板函数" << endl;return a + b;
}
add(1, 2);  // 调用普通函数

六、函数模版实例化图解

template <typename T>

用户调用:add(1.0, 2.0)

编译器推导:T = double

实例化:生成 double add(double, double)

参与编译,生成可执行代码


总结

  • 函数模板提供类型参数化的机制,实现泛型编程。

  • 实例化是编译器根据调用自动或显式生成对应代码的过程。

  • 模板代码通常放在头文件中。

  • 函数模板实例化支持隐式、显式、特化等方式。

http://www.xdnf.cn/news/1242667.html

相关文章:

  • 飞算JavaAI需求转SpringBoot项目沉浸式体验
  • 【BUUCTF系列】[极客大挑战 2019]LoveSQL 1
  • vllm启动Qwen/Qwen3-Coder-30B-A3B-Instruct并支持工具调用
  • MLIR Introduction
  • android内存作假通杀补丁(4GB作假8GB)
  • History 模式 vs Hash 模式:Vue Router 技术决策因素详解
  • ZYNQ-按键消抖
  • JavaScript 中的流程控制语句详解
  • 3.JVM,JRE和JDK的关系是什么
  • 第二十四天(数据结构:栈和队列)队列实践请看下一篇
  • SQL注入SQLi-LABS 靶场less39-50详细通关攻略
  • 基于实时音视频技术的远程控制传输SDK的功能设计
  • 【ECCV2024】AdaCLIP:基于混合可学习提示适配 CLIP 的零样本异常检测
  • [GESP202306 四级] 2023年6月GESP C++四级上机题超详细题解,附带讲解视频!
  • 刷题记录0804
  • ref和reactive的区别
  • 8位以及32位的MCU如何进行选择?
  • ArrayDeque双端队列--底层原理可视化
  • Redis 常用数据结构以及单线程模型
  • LeetCode 140:单词拆分 II
  • Array容器学习
  • app-1
  • 优选算法 力扣 11. 盛最多水的容器 双指针降低时间复杂度 贪心策略 C++题解 每日一题
  • Javascript面试题及详细答案150道之(031-045)
  • python包管理器uv踩坑
  • 力扣面试150题--加一
  • PCL统计点云Volume
  • ArcGIS的字段计算器生成随机数
  • 配置Mybatis环境
  • 【多智能体cooragent】CoorAgent 系统中 5 个核心系统组件分析