黑马课程C++笔记 | 函数模板与类模板

模板

  • C++另一种编程思想称为泛型编程
  • C++提供两种模板机制:函数模板类模板

注:<typename T> 或者 <class T> 都可以,使用前者可以用来与后者做区分。但如果不需要区分,可以全用代码也不会出错


1.函数模板

1.1函数模板语法

函数模板作用

建立一个通用函数,其返回值类型和形参类型可以不具体制定,用一个虚拟的类型来代表


语法:template<typename T>(后接函数声明或定义)
Template:声明创建模板
Typename:表明其后面的符号是一种数据类型,可以用class代替
T:通用的数据类型,名称可以替换,通常为大写字母


1.2函数模板注意事项

注意事项:

  • 自动类型推导,必须推导出一致的数据类型T才可以使用

  • 模板必须确定出T的数据类型,才可以使用


1.3普通函数与函数模板的区别

普通函数与模板函数的区别:

  • 普通函数调用时可以发生自动类型转换(隐式类型转换)

  • 函数模板调用时,如果用自动类型推导,不会发生隐式类型转换

  • 如果利用显示指定类型的方式,可以发生隐式类型转换


例:int a = 10; char b = 'a';

1.普通加法函数 myAdd(a, b) 返回值为 10 + 97 = 107

2.函数模板 myAdd(a, b) 显示错误,无法对不同数据类型的参数发生隐式类型转换

3.函数模板 myAdd(a, b) 指定类型时,返回值 10 + 97 = 107


1.4普通函数与函数模板的调用规则

调用规则如下:

  • 如果函数模板和普通函数都可以实现,优先调用普通函数

  • 如果通过空模板参数列表来强制调用函数模板

  • 函数模板也可以发生重载

  • 如果函数模板可以产生更好的匹配,优先调用函数模板


1.5模板的局限性

局限性:

  • 模板的通用性不是万能的

例:为了让person类的值可以用函数模板进行比较操作

总结:

  • 利用具体化的模板,可以解决自定义类型的通用化

  • 学习模板并不是为了写模板,而是在STL能够运用系统提供的模板


2.类模板
2.1类模板语法

类模板作用:
建立一个通用类,类中的成员、数据类型不具体制定,用一个虚拟的类型来表示

语法:template<typename T>类

总结:

  • 类模板和函数模板语法类似

  • 函数模板下接函数,类模板下接类


2.2类模板与函数模板的区别

类模板与函数模板区别主要有两点:

  • 类模板没有自动类型推导的使用方式,只能用显示指定类型方式

  • 类模板在模板参数列表中可以有默认参数


2.3类模板中成员函数创建时机

类模板中成员函数和普通类中成员函数创建时机是有区别的:

  • 普通类中的成员函数一开始就可以创建

  • 类模板中的成员函数在调用时才创建


2.4类模板对象做函数参数

学习目标:类模板实例化出的对象,向函数传参的方式


一共有三种传入方式
例:

  • 指定传入的类型:直接显示对象的数据类型(最常用!)

  • 参数模板化:将对象中的参数变为模板进行传递

  • 整个类模板化:将这个对象类型 模板化进行传递

注:typeid(T).name()可以使T的数据类型以string的方式输出到屏幕上


2.5类模板与继承

注意:

  • 当子类继承的父类是一个类模板时,子类在声明的时候,要指定出父类中T的类型

  • 如果不指定,编译器无法给子类分配内存

  • 如果想灵活指出父类中T的类型,子类也需变为类模板


2.6类模板成员函数类外实现

  • 类内实现

  • 类外实现


2.7类模板分文件实现

学习目标:掌握类模板成员函数分文件编写产生的问题以及解决方式

问题:类模板中成员函数创建时机是在调用阶段,导致分文件编写时链接不到

解决:

  • 法一:直接包含.cpp源文件
    注:声明放在.h头文件中,定义放在.cpp文件中,main文件中
    不写#include“xx.h”而是#include“xx.cpp”

  • 法二:将声明和实现写到同一个文件中,并更改后缀名为.hpp,hpp是约定的名称,并不是强制

注:声明和定义放在.h文件中,并更后缀为.hpp,在main文件中包含“xx.hpp”

注:法二是主流的解决办法!


2.8类模板和友元

  • 全局函数类内实现:直接在类内声明友元即可

  • 全局函数类外实现:需要提前让编译器知道全局函数的存在


posted @   不是勇士  阅读(306)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示