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

C++模板之——类模板详解及代码示例

引言

上一篇文章,我们聊了C++的函数模板,今天我们来聊聊类模板。

一、类模板

1.1 作用

建立一个通用类,类中的成员和数据类型可以不具体指定,使用一个虚拟的类型来代替。
语法:

template<typename T>
类声明或者定义

说明:
template —— 表明要创建类模板。
typename —— 表示一种数据类型,可以用 class 代替, T 就是具体的名称,通常为大写字母。

1.2 代码示例

#include <iostream>
#include <string>
using namespace std;

// 类模板
template<class nameType, class ageType>
class Person{

public:
    Person(nameType name, ageType age){
        this->m_name = name;
        this->m_age = age;
    }    
    nameType m_name;
    ageType m_age;
};

int main(int argc, char* argv[])
{
    Person<string, int> p1("panda", 20);
    std::cout << "p1.name: " << p1.m_name << " p1.age: "<< p1.m_age<< std::endl;
    return 0;
}

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

  • 类模板没有自动类型的推到使用方法
  • 类模板可以再模板参数列表中有默认参数类型
// 类模板
template<class nameType, class ageType = int> // ageType类型默认为int
class Person{
public:
    Person(nameType name, ageType age){
        this->m_name = name;
        this->m_age = age;
    }    
    nameType m_name;
    ageType m_age;
};
int main(int argc, char* argv[])
{
    Person<string, int> p1("panda", 20);
    std::cout << "p1.name: " << p1.m_name << " p1.age: "<< p1.m_age<< std::endl;
    
    // Person p("panda", 20); // 错误,不能自己推导数据类型
    Person<string> p2("lwang", 20);
    std::cout << "p2.name: " << p2.m_name << " p2.age: "<< p2.m_age<< std::endl;
    return 0;
}

运行结果:
在这里插入图片描述

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

  • 普通类函数成员一开始就可以创建出来
  • 类模板中的函数成员只有在调用的时候才创建

示例:

class Student{
public:
    void showStudentInfo()
    {
        std::cout << "Student show." << std::endl;
    }
};

class Teacher{
public:
    void showTeacherInfo()
    {
        std::cout << "Teacher show." << std::endl;
    }
};

template<class T>
class Person{
public:
    T obj;

    // 成员函数
    void func1()
    {
        obj.showStudentInfo();
    }

    void func2()
    {
        obj.showTeacherInfo();
    }
};

int main(int argc, char* argv[])
{
    Person<Student> pStu;
    pStu.func1();
    // pStu.func2();  // 在确认Person的T的类型为Student后,编译器发现obj没有func2,编译报错

    Person<Teacher> pTe;
    // pTe.func1(); // 在确认Person的T的类型为Teacher后,编译器发现obj没有func1,编译报错
    pTe.func2();
    return 0;
}

运行结果:
在这里插入图片描述

1.4 类模板对象作为函数的参数如何传递

类模板实例化出的对象,作为函数的参数传递的方式有三种:

  1. 显示指定传入的类型
  2. 参数模板化
  3. 整个类模板化
template<class nameType, class ageType = int> // ageType类型默认为int
class Person{
public:
    Person(nameType name, ageType age){
        this->m_name = name;
        this->m_age = age;
    }    
    nameType m_name;
    ageType m_age;
};

void showPerson1(Person<string> &p)
{
    std::cout << "p.name: " << p.m_name << " p.age: "<< p.m_age<< std::endl;
}

template<class T1, class T2>
void showPerson2(Person<T1, T2>& p)
{
    std::cout << "p.name: " << p.m_name << " p.age: "<< p.m_age<< std::endl;
    // std::cout << "T1 type is: " << typeid(T1).name() << std::endl;
    // std::cout << "T2 type is: " << typeid(T2).name() << std::endl;
}

template<class T>
void showPerson3(T& p)
{
    std::cout << "p.name: " << p.m_name << "   p.age: "<< p.m_age<< std::endl;
    // std::cout << "T type is: " << typeid(T).name() << std::endl;
}


int main(int argc, char* argv[])
{
    // 1. 显式指定参数类型
    Person<string> p("panda", 20);
    showPerson1(p);

    Person<string, int> p1("lwang", 35);
    // 2. 参数模板化
    showPerson2(p1);

	// 3. 整个类模板化
    Person<string, int> p2("lyz", 18);
    showPerson3(p2);
    return 0;
}

运行结果:
在这里插入图片描述

相关文章:

  • Python推荐系统和深度学习教程
  • 基于Matlab使用雷达资源管理有效跟踪多个机动目标仿真(附源码)
  • 医院管理系统/医院药品管理系统
  • 项目中使用到的Spring注解及其作用
  • Postgresql源码(86)varchar的创建与插入分析
  • VMware创建虚拟机及安装Linux操作系统
  • 基于51单片机的指纹考勤机密码锁系统
  • 科研小白上路的必备工具链
  • HTML5七夕情人节表白代码 (动态3D相册) HTML+CSS+JS
  • 【云原生 | 从零开始学istio】一、Istio介绍—服务网格
  • 花咲の姫君(異時層ツキハ) / 花咲(异时层妖刀)
  • 体系结构实验(6)—— Cache映射策略
  • 牛客网专项练习30天Pytnon篇第16天
  • 【DS】6.堆知识总结!!!
  • kali工具熟悉——存活主机识别
  • Angular 4.x 动态创建组件
  • canvas 高仿 Apple Watch 表盘
  • Java|序列化异常StreamCorruptedException的解决方法
  • JavaScript 奇技淫巧
  • JDK 6和JDK 7中的substring()方法
  • Vue全家桶实现一个Web App
  • webpack+react项目初体验——记录我的webpack环境配置
  • 给第三方使用接口的 URL 签名实现
  • 如何学习JavaEE,项目又该如何做?
  • 小程序、APP Store 需要的 SSL 证书是个什么东西?
  • 06-01 点餐小程序前台界面搭建
  • 智能情侣枕Pillow Talk,倾听彼此的心跳
  • ​无人机石油管道巡检方案新亮点:灵活准确又高效
  • # include “ “ 和 # include < >两者的区别
  • (1)bark-ml
  • (Demo分享)利用原生JavaScript-随机数-实现做一个烟花案例
  • (pytorch进阶之路)扩散概率模型
  • (TOJ2804)Even? Odd?
  • (带教程)商业版SEO关键词按天计费系统:关键词排名优化、代理服务、手机自适应及搭建教程
  • (论文阅读32/100)Flowing convnets for human pose estimation in videos
  • (十八)三元表达式和列表解析
  • (一)Linux+Windows下安装ffmpeg
  • (译)计算距离、方位和更多经纬度之间的点
  • (轉貼) UML中文FAQ (OO) (UML)
  • **CI中自动类加载的用法总结
  • .MSSQLSERVER 导入导出 命令集--堪称经典,值得借鉴!
  • .NET Compact Framework 3.5 支持 WCF 的子集
  • .net core webapi Startup 注入ConfigurePrimaryHttpMessageHandler
  • .NET Framework 的 bug?try-catch-when 中如果 when 语句抛出异常,程序将彻底崩溃
  • .Net 代码性能 - (1)
  • .so文件(linux系统)
  • /var/spool/postfix/maildrop 下有大量文件
  • @EnableAsync和@Async开始异步任务支持
  • [ 转载 ] SharePoint 资料
  • [20150707]外部表与rowid.txt
  • [2018/11/18] Java数据结构(2) 简单排序 冒泡排序 选择排序 插入排序
  • [Angular] 笔记 18:Angular Router
  • [Angularjs]ng-select和ng-options
  • [bzoj1912]异象石(set)
  • [c#基础]值类型和引用类型的Equals,==的区别