C++开发基础——类模板

C++模板编程入门:从函数模板到类模板的实战指南 泛型编程是一种编程范式,其核心思想是编写独立于数据类型的代码,以提高代码的复用性和安全性。在C++中,这一思想主要通过模板技术实现,它允许将类型作为参数,在编译时生成针对特定类型的代码。模板的技术价值在于实现了类型安全的通用算法和数据结构,避免了代码重复,是构建标准模板库(STL)等高性能库的基石。其应用场景广泛,从简单的交换函数、通用容器(如vector、map),到智能指针、类型萃取等高级工具都依赖模板。本文聚焦于C++模板的初阶核心,深入解析函数模板与类模板的语法、实例化机制、模板参数(包括非类型参数 阅读详情

一,基础定义

类模板是用来生成类的蓝图,是一种创建类的方式,同一套类模板可以生成很多种不同的类。

编译器基于类模板生成的每个类被称为类模板的实例。

第一次使用模板类型声明变量时,会创建类模板的一个实例, 以后定义同类型的变量时,会使用已经创建的第一个实例。

类模板有许多应用,最常见的应用是定义容器类。

类模板和类一样,可以有友元,其友元可以是类,函数或者其他模板。

如果一个派生类继承自该类模板,那么这个派生类也必须是模板。

类模板的代码样式:

template <parameter list>
class ClassName
{
    //class definition ...
}

类型模板参数 & 非类型模板参数图示:

代码样例:用类模板实现的Array<T>

template <typename T>
class Array
{
private:
    T* elements;
    size_t size;
public:
    explicit Array<T>(size_t arraySize);      //构造函数
    Array<T>(const Array<T>& array);          //拷贝构造函数
    ~Array<T>();                              //析构函数
    T& operator[](size_t index);              //下标运算符
    Array<T>& operator=(const Array<T>& rhs); //赋值运算符
    size_t getSize() const {return size;}
};

在类模板的内部,可以直接使用类模板名称,不需要显式地带模板参数,因此,在类模板的内部,Array和Array<T>等价。

以上代码可以简化为:

template <typename T>
class Array
{
    private:
        T* elements;
        size_t size;
    public:
        explicit Array(size_t arraySize);
        Array(const Array& array);
        ~Array();
        T& operator[](size_t index);
        Array& operator=(const Array& rhs);
        size_t getSize() const {return size; }
};

类模板参数指定默认值的方式和函数参数一样。

默认值在类模板的声明中指定即可,不需要在成员函数模板中指定默认值。

定义类模板的时候也可以这样写: 

template <typename T=string>
class Array
{
    //code
}

使用默认值来实例化类模板,可以这样写:

Array<> myArray;

二,类模板的成员函数

在类模板的模板体中定义的成员函数,与普通的类一样,成员函数可以看作是所有模板实例的内联函数。

但是在模板体的外部定义的成员函数,语法与普通的类不同,需要将成员函数定义为函数模板。

由于成员函数的函数模板与它们的类模板绑定在一起,所以函数模板使用的参数列表必须与类模板的参数列表完全相同。

1.构造函数模板:

template <typename T>
Array<T>::Array(size_t arraySize):
elements{new T[arraySize]}, size{arraySize}
{

}

2.拷贝构造函数模板:

假定赋值运算符可以用于T类型的变量。

template <typename T>
Array<T>::Array(const Array& array): Array{array.size}
{
    for (size_t i {}; i < size; ++i)
    {
        elements[i] = array.elements[i];
    }
}

3.析构函数模板:

释放给数组分配的堆内存。

template <typename T>
Array<T>::~Array()
{
    delete[] elements;
}

4.下标运算符模板:

template <typename T>
T& Array<T>::operator[](size_t index)
{
    if (index >= size)
    {
        throw std::out_of_range {"Index too large: " + std::to_string(index)};
    }
    return elements[index];
}

5.赋值运算符模板:

template <typename T>
Array<T>& Array<T>::operator=(const Array& rhs)
{
    if (&rhs != this)
    {
        delete[] elements;
        size = rhs.size;
        elements = new T[size];  //may throw std::bad_alloc
        for(size_t i {}; i < size; ++i)
        {
            elements[i] = rhs.elements[i];
        }
    }
    return *this;
}

由类模板创建模板实例时,并不会把所有的成员函数的函数模板都拿去生成模板实例,只有被代码用到的成员函数才会被生成模板实例,例如,由类模板生成某个类时,这个类只进行了创建对象的操作,只有构造函数和析构函数的函数模板会生成模板实例,其他暂时没用到的函数模板,比如拷贝构造函数模板,则不会生成模板实例。简单讲就是,当实例化一个类模板时,它的成员函数对应的函数模板只有在使用时才会被实例化。

声明指向对象的指针并不会创建类模板的实例:

Array<std::string>* obj_ptr;  
//声明了一个指针,不会创建类模板的实例

Array<std::string*> str_obj {10};
//定义了一个对象,会创建类模板的实例,同时还会生成构造函数的函数模板实例

三,非类型模板参数

非类型参数是指模板定义中,带有指定类型的参数。

非类型参数的主要用途是指定容器的大小和上下限。

代码样例如下:

template <typename T, size_t size> //size: 非类型参数
class ClassName

{
    //code
};

注意:类型参数T必须放在非类型参数size的前面。

非类型模板参数还可以在定义的时候给一个初始值,例如:

template <typename T, size_t size = 10>
class ClassName
{
    //code
};

非类型参数支持的数据类型:

整数类型(例如size_t、long)
枚举类型
对象的指针or引用类型
函数的指针or引用类型

非类型参数不支持浮点类型或类类型。

从C++17开始,也可以指定auto,auto& 和 auto* 等作为非类型参数,编译器会自动推导出类型。

代码样例:

a.带有非类型参数的Array类模板:

template <typename T, int startIndex>
class Array

{
private:
    T* elements;
    size_t size;
public:
    explicit Array(size_t arraySize);
    Array(const Array& array);
    ~Array();
    T& operator[](int index);
    Array& operator=(const Array& rhs);
    size_t getSize() const { return size; }
}

b.带有非类型参数的成员函数模板

1.构造函数模板:

template <typename T, int startIndex>
Array<T, startIndex>::Array(size_t arraySize):
elements{new T[arraySize]}, size{arraySize}
{

}

2.拷贝构造函数模板:

template <typename T, int startIndex>
Array<T, startIndex>::Array(const Array& array): Array{array.size}
{
    for (size_t i {}; i < size; ++i)
    {
        elements[i] = array.elements[i];
    }
}

3.析构函数模板:

template <typename T, int startIndex>
Array<T, startIndex>::~Array()
{
    delete[] elements;
}

4.下标运算符模板:

template <typename T, int startIndex>
T& Array<T, startIndex>::operator[](int index)
{
    return const_cast<T&>(std::as_const(*this)[index]);
}

5.赋值运算符模板:

template <typename T, int startIndex>
Array<T, startIndex>& Array<T, startIndex>::operator=(const Array& rhs)
{
    if (&rhs != this)
    {
        delete[] elements;
        size = rhs.size;
        elements = new T[size];  //may throw std::bad_alloc
        for(size_t i {}; i < size; ++i)
        {
            elements[i] = rhs.elements[i];
        }
    }
    return *this;
}

非类型模板参数在使用时需要注意,给非类型参数传不同的实参,将生成不同的模板实例。

代码样例:

以下代码将创建两个不同的模板实例

Array<double, 0> obj1{10};
Array<double, 1> obj2{10};

四,类模板的特例

和函数模板一样,类模板也有特例,被称为类模板的具体化。

当有些模板参数只适用于特定的数据类型,比如可以使用string类型实例化模板,但使用char*类型实例化模板时会报错,此时需要定义类模板的特例。

代码样例:

template <>
class Array<const char*>
{
};

类模板特例的定义必须在原始类模板的定义之后。

五,参考阅读

《C++17入门经典》

《C++ Primer》

C++类模板 类模板 1.3.1 类模板语法 类模板作用: 建立一个通用类,类中的成员 数据类型可以不具体制定,用一个虚拟的类型来代表。 语法: template<typename T> 类 解释: template — 声明创建模板 typename — 表面其后面的符号是一种数据类型,可以用class代替 T — 通用的数据类型,名称可以替换,通常为大写字母 示例: #include <string> //类模板 template<class NameType, c 阅读详情

相关推荐

C++ 设计模式3:单例模式

单例 Singleton 是设计模式的一种,其特点是只提供唯一一个类的实例,具有全局变量的特点,在任何位置都可以通过接口获取到那个唯一实例;具体运用场景如:设备管理器,系统中可能有多个设备,但是只有一个设备管理器,用于管理设备驱动;数据池,用来缓存数据的数据结构,需要在一处写,多处读取或者多处写,多处读取;

琅嬛福地 2732

入门指南:C++ 模板类详解

入门指南:C++ 模板类详解

qq_46017342的博客 6332

c++模板类作为基类-模板子类访问基类成员的方法

c++模板类作为基类-模板子类访问基类成员的方法

digitalkee的博客 1221

C++中的模板类

什么是模板类:C++发展到一定层次后,必然有部分代码存在仅传参的数据类型不同而内容一致的情况。因此,C++为解决此类场景,特推出模板类的使用。模板类是一种泛型技术,即与数据类型无关的通用程序设计技术。可以使我们设计出独立于数据类型的程序。模板类本身不占空间,当编译器执行到模板参数的调用时,当在程序中赋予具体的数据类型后并调用时则占用空间。常见的模板包含函数模板与类模板。模板的声明中class含义同typenamec,class并不是表明后续的类型名是一个类,而表示后续是一个通用的类型说明符。一、函数模板函数

qq_39645539的博客 1万+

AI气象预报:数值模式融合与短临预警的工程实践

气象预报正经历从物理推演到数据驱动的认知范式转变。AI气象预报并非替代传统数值模式,而是通过数值模式融合弥补其在参数化误差、初值敏感性和计算效率上的固有瓶颈。其技术价值在于提升短临预警时效性与空间精度,支撑航空调度、电力调控、防洪应急等关键场景。实践中需兼顾物理一致性、可解释性与业务系统兼容性,避免纯黑箱建模带来的外推失效与不确定性缺失风险。本文聚焦AI作为超分辨率引擎、误差矫正器和短临加速器的三类落地路径,解析HEALPix投影、多尺度图建模、轻量级U-Net等核心适配方法。

weixin_28221501的博客 298

【深度解析】信息素养提升实践活动(附:历年获奖作品分析)

全国师生信息素养提升实践活动是由教育部教育技术与资源发展中心(中央电化教育馆)主办,面向全国师生的一项信息化交流展示活动。

m0_74417957的博客 2628

XCode5添加新建类模板(Cocos2dx Template Class for Scene or Layer)

猴子原创,欢迎转载。转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢!原文地址: http://www.cocos2dev.com/?p=505因为常用cocos2dx开发游戏,所以每次新建cpp类文件的时候,XCode默认生成的cpp类基本就是一个空文件,每次都要重复实现cocos2dx的基本代码。很麻烦。(虽然我每次都是修改了HelloWorld文件,新建的文件直接c

Cocos2der Game 7070

U8备份提示“远程组件初始化失败”

问题现象: SQL出现问题后重装,U8没有重装,之后直接附加数据库,U8可以正常登陆,但是在备份的时候提示远程组件初始化失败。 问题原因: 因为重装了SQL,没有进行U8数据源初始化,导致Master库中丢失了存储过程储 解决办法:在Master库重建存储过程 USE [master] GO SET ANSI_NULLS OFF GO SET QUOTED_IDENTIFIER OFF GO CREATE PROCEDURE [dbo].[U8FileServerExtendProc] @cmdLi.

SamYux 2473

Cpp-Templates-2ed完全指南:从C++11到C++20的终极模板编程教程

C++模板是C++11至C++20标准中最复杂也最强大的特性之一,是构建高性能基础设施库不可或缺的技术。本教程将带你从基础到进阶,全面掌握现代C++模板编程的核心技术与最佳实践。 ## 为什么模板是C++开发者的必备技能 🚀 模板作为C++的元编程基础,允许开发者编写与类型无关的通用代码,在保持类型安全的同时实现代码复用。无论是STL标准库、Boost库,还是现代C++基础设施,模板技术都扮

gitblog_00195的博客 683

DA14531-外设驱动篇-UART收发通信应用

宏定义注解CFG_PRINTF用户开启串口串口打印宏设置波特率选择115200。

hejinwu1314的博客 729

把数字化转型真正落到组织里:读懂 SAP 的 OCM 六维框架

摘要: SAP的变革管理框架(OCM)强调数字化转型不仅是技术任务,更需关注组织与人的适应性。OCM包含六大维度:变革战略(明确方向与风险)、变革领导力(统一关键管理者行动)、变革沟通(分层传递信息)、变革实现(细化岗位级影响)、变革赋能(按角色设计培训)和变革有效性(持续评估)。该框架贯穿项目全周期,尤其在云项目中,需从早期规划变革策略,避免后期高代价调整。OCM的核心是将系统设计转化为组织语言,确保业务真正采纳新方式运作。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1433

2024年大数据最全全面总结C++类模板使用的基础知识_c++模板怎么用,2024年最新2024年大数据开发开发实战

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。需要这份系统化资料的朋友,可以戳这里获取一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!可以看到第一行代码T2的后面指定了类型为整型,所以创建类模板对象的时候可以省略T2数据类型的指定,但是切记 :在不给参数列表最后一个虚拟类型指定数据类型的情况下是无法

2401_84586380的博客 411

022、Conv-BN-SiLU 基础卷积块:构造函数参数计算,前向传播的 PyTorch 逐行实现

本文详细解析了Conv-BN-SiLU卷积块的实现细节与注意事项。作者从调试经历出发,指出bias参数冗余会导致数值不稳定,强调卷积层应设置bias=False。文章对比了SiLU与ReLU的特性差异,逐行分析了构造函数参数计算(包括自动填充、分组卷积等)和前向传播过程,特别讲解了BN层与SiLU激活的数值特性。最后分享了三个实践中的常见问题:BN的momentum设置、SiLU输出范围的影响,以及分组卷积的通道对齐要求,并提供了卷积与BN融合的推理优化技巧。全文聚焦实际工程实现中的关键细节,具有较强实操指

ai技术增长的博客 217

C++模板初阶:从函数模板到类模板

本文介绍了C++模板的基础概念,包括函数模板和类模板。函数模板通过参数化类型实现代码复用,支持隐式和显式实例化,遵循特定的匹配原则。类模板允许创建通用的数据结构,如栈类模板。两者实例化方式不同,类模板需要显式指定类型参数。文章还提示了模板定义不应分离到不同文件以避免链接错误,为后续学习模板特化等进阶内容奠定基础。

is_ko_nois_ko的博客 550

一文看懂 SAP Integration Suite:从架构治理、接口编排到事件驱动的集成全景

SAP Integration Suite是企业数字化转型中的关键集成平台,通过统一的方法论和工具链解决系统互联、数据对齐和流程协同等复杂问题。其核心能力包括:1)集成评估(Integration Assessment)提供战略规划框架;2)迁移评估(Migration Assessment)支持从传统平台向云的平滑过渡;3)云集成(Cloud Integration)实现日常业务流程编排;4)集成顾问(Integration Advisor)简化B2B标准映射;5)贸易伙伴管理(TPM)优化外部协作流程;

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 501

基于四旋翼模型的火箭型无人机视线角保持控制仿真设计

本文针对火箭型无人机的视线角保持控制问题展开研究。基于四旋翼动力学模型,通过改造设计了一种摄像头朝上安装的特殊无人机系统,用于追踪空中目标。文章详细推导了坐标系定义、运动学和动力学方程,重点分析了摄像头安装与视线几何关系,建立了目标运动模型和视线向量计算方法。通过解算期望姿态角,实现了使机体Z轴始终对准目标的控制目标。仿真结果表明,该系统能有效完成视线角保持任务,为空对空监视等应用场景提供了可行方案。~~~~~

huanghm88的专栏 140

【C++17 core language features】深入解析 C++17 中的类模板参数推导

在C++的发展过程中,模板编程一直是语言强大功能的重要组成部分。类模板参数推导(Class Template Argument Deduction, CTAD)作为C++17引入的一个标志性特性,极大地简化了类模板的使用方式,提升了代码的简洁性和可读性。正如亚里士多德所说:“知识即力量。” 通过理解并掌握类模板参数推导,开发者能够更高效地利用C++的模板编程能力,编写出更加优雅和高效的代码。

探索C++编程的奥秘,分享深入的技术见解和实践,旨在激发读者创造力与解决问题的思维。 1191

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

【C++篇】C++模板初阶:从泛型编程到函数模板与类模板的全面解析

看双向链表可知,这是一个典型的中序遍历,左节点、节点、右节点的顺序,那么双向链表的节点顺序解决了,就要考虑节点的链接,前驱节点直接链接上一个中序遍历的节点,后驱节点则是下一个,最后返回最左下角的节点(即。首先我们要知道,前序是按照先左根再右根的顺序进行,这也决定了他是二叉树中根的顺序,其次中序的遍历方式我们可以发现找到前序中的根,那么其左右区间就是左右子树,按照此种方法不断划分,就是利用的分治思想。排除了p或q为根节点的情况,那么剩余的情况必定在根节点以下的节点,发现用向下递归的方法,

小白技术的博客 934

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

C++泛型编程入门:函数模板与类模板实战解析

泛型编程是一种将数据类型参数化的编程范式,其核心思想是通过编写独立于特定类型的代码来提高复用性和灵活性。在C++中,这一思想主要通过模板技术实现,包括函数模板和类模板。模板在编译期进行实例化,能够生成针对具体类型的高效特化代码,从而实现零开销抽象。这项技术是构建高性能、可复用库(如STL)的基石,广泛应用于容器、算法等场景。本文以C++模板为核心,结合函数模板和类模板的实战案例,深入解析模板的编译模型、特化技巧及常见问题,帮助开发者掌握这一提升代码质量的关键工具。

weixin_30663839的博客 231

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

C++ 中函数模板和类模板有什么区别?

摘要: C++中的函数模板和类模板均支持参数化编程,但存在显著差异。函数模板通过隐式实例化(编译器自动推导类型)实现通用算法,适用于逻辑相同但数据类型不同的场景(如排序)。类模板需显式指定类型参数,用于构建通用数据结构(如栈、队列),其成员函数在实例化时全部生成。 特化方面,函数模板仅支持全特化(针对特定类型优化算法),而类模板支持全特化和部分特化(调整数据结构或行为)。函数模板特化语法简单,仅影响局部逻辑;类模板特化可能重构整体设计,复杂度更高。 影响: 函数模板:提升算法灵活性,维护简单,适合类型相关的

weixin_45422672的博客 1017

C++类模板:从基础语法到实战应用全解析

模板是C++实现泛型编程的核心机制,它通过在编译期生成类型特定的代码,实现了算法和数据结构的高度复用。类模板作为模板的重要分支,专注于数据结构的泛化,允许开发者定义可参数化类型的类。其核心价值在于提升代码的通用性和可维护性,避免为不同数据类型重复编写相似逻辑。在工程实践中,类模板广泛应用于标准库容器(如vector、list)、智能指针等场景,是实现高性能、类型安全组件的基石。本文深入探讨类模板的语法细节、实例化机制及与函数模板的本质区别,并解析了模板参数传递、继承关系等高级主题,帮助开发者掌握这一关键技术

weixin_32576389的博客 238

【C++ 模板入门】:从泛型编程到函数/类模板详解

class 类模板名 {// 类内成员定义public:_size = 0;// 注意:模板定义和声明不能分离到 .h 和 .cpp,否则链接出错// 扩容逻辑(这里简化)++_size;C++ 模板是一个强大的工具,帮助实现泛型编程,避免重复代码。通过函数模板和类模板,我们可以编写通用代码,让编译器处理类型细节。初学者注意:模板在编译期工作,多练习实例化原理,避免常见错误如类型不匹配。

2403_87140900的博客 342

C++类模板:泛型编程核心,从基础语法到智能指针与容器实现

泛型编程是一种编程范式,其核心思想是编写独立于数据类型的代码,以提高代码的复用性和安全性。在C++中,这一思想主要通过模板机制实现,其中类模板允许开发者定义可处理任意类型的类蓝图。其工作原理是编译器根据提供的具体类型进行实例化,生成类型安全的特定类。这种技术价值在于它能显著减少代码重复,提升库代码的可维护性和性能,是STL(标准模板库)的基石。应用场景广泛,从实现通用容器(如动态数组Vector)、资源管理工具(如智能指针UniquePtr)到构建复杂算法库都离不开类模板。本文以C++类模板为主题,深入解析

weixin_34258838的博客 425

C++模板编程:从函数模板到类模板,掌握泛型编程核心

泛型编程是C++中实现代码复用和类型安全的核心技术,它允许开发者编写独立于数据类型的通用算法和数据结构。其原理是通过模板机制,在编译期根据具体类型生成特化代码,从而实现零运行时开销的抽象。这种技术价值在于显著提升代码的复用性、可维护性和性能,是构建如STL标准库等大型软件基础设施的基石。在实际应用场景中,泛型编程广泛用于容器类、算法库、元编程和设计模式实现。本文聚焦于C++模板编程,深入解析函数模板与类模板的实战应用,并探讨模板特化、可变参数模板等进阶技巧,帮助开发者规避代码膨胀等常见陷阱,提升工程实践能力

weixin_34161083的博客 523

c++--候捷视频学习(四)类模板、函数模板、namespace用法、结构体

一、类模板 二、函数模板 三、namespace用法

weixin_41012399的博客 163
上一篇: C++开发基础——IO操作与文件流
下一篇: C++开发基础——类对象与构造析构
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员与背包客_CoderZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值