【c++】类模版

2023-11-17

1、类模板语法

类模板作用:

  • 建立一个通用类,类中的成员 数据类型可以不具体制定,用一个虚拟的类型来代表。

语法:

template<typename T>
类

解释:

template --- 声明创建模板

typename --- 表面其后面的符号是一种数据类型,可以用class代替

T --- 通用的数据类型,名称可以替换,通常为大写字母

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

template <class nameType,class ageType>
class Person
{
public:
	Person(nameType name,ageType age):m_Name(name),m_Age(age)
	{}

	nameType m_Name;
	ageType m_Age;

	void printInfo()
	{
		cout << "姓名是:" << this->m_Name << "  年龄是:" << this->m_Age << endl;
	}
};

void test01()
{
	//通过类模版来实例化对象
	Person <string, int> person("张三", 33);
	person.printInfo();
}

int main(void)
{
	test01();

	system("pause");
	return 0;
}

总结:类模板和函数模板语法相似,在声明模板template后面加类,此类称为类模板

2、类模板与函数模板区别

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

      (1)类模板没有自动类型推导的使用方式

      (2)类模板在模板参数列表中可以有默认参数

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

//2. 类模板在模板参数列表中可以有默认参数
template <class nameType,class ageType = int>
class Person2
{
public:
	Person2(nameType name,ageType age) :m_Name(name), m_Age(age)
	{

	}
	void showInfo()
	{
		cout << "name:" << this->m_Name << "  age:" << this->m_Age << endl;
	}

	nameType m_Name;
	ageType m_Age;
};

//1. 类模板没有自动类型推导的使用方式
//2. 类模板在模板参数列表中可以有默认参数

void test02()
{
	1. 类模板没有自动类型推导的使用方式
	//Person2 p("李四",10);         错误:无法进行类型推导
	Person2<string, int>person("张三", 11);
	person.showInfo();

	//2. 类模板在模板参数列表中可以有默认参数
	Person2<string>person1("李四", 12);
	person1.showInfo();
}

int main(void)
{
	test02();

	system("pause");
	return 0;
}

总结:

  • 类模板使用只能用显示指定类型方式

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

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

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

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

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

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


// 普通类中的成员函数一开始就可以创建
// 类模板中的成员函数在调用时才创建

class Person3
{
public:
	void showPerson3()
	{
		cout << "Person3 show" << endl;
	}
};

class Person33
{
public:
	void showPerson33()
	{
		cout << "Person33 show" << endl;
	}
};

template<class T>
class MyClass
{
public:
	T obj;
	
	//类模版中的成员函数
	void func1()
	{
		obj.showPerson3();
	}
	void func2()
	{
		obj.showPerson33();
	}
};


int main(void)
{
	test03();

	system("pause");
	return 0;
}

这是可以编译成功的。

再加上调用的函数,就会报错,说明类模板中的成员函数在调用时才创建

void test03()
{
	MyClass<Person3>p1;
	p1.func1();
	//p1.func2();   //编译会出错,说明函数调用才会去创建成员函数
}

4、类模板对象做函数参数

一共有三种传入方式:

     (1)指定传入的类型 --- 直接显示对象的数据类型

     (2)参数模板化 --- 将对象中的参数变为模板进行传递

     (3)整个类模板化 --- 将这个对象类型 模板化进行传递

 

(1)指定传入的类型 --- 直接显示对象的数据类型

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

//类模版
template<class T1,class T2>
class Person4
{
public:
	//构造函数
	Person4(T1 name,T2 age):m_Name(name),m_Age(age)
	{
	}
	//显示函数
	void showPerson()
	{
		cout << "姓名:" << this->m_Name << endl;
		cout << "年龄:" << this->m_Age << endl;
	}

	T1 m_Name;
	T2 m_Age;
};

//1、指定传入的类型
void printPerson1(Person4<string,int>&p)
{
	p.showPerson();
}
void test04()
{
	Person4<string, int>p("孙悟空", 123);
	printPerson1(p);
}

int main(void)
{
	test04();

	system("pause");
	return 0;
}

(2)参数模板化 --- 将对象中的参数变为模板进行传递

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

//类模版
template<class T1,class T2>
class Person4
{
public:
	//构造函数
	Person4(T1 name,T2 age):m_Name(name),m_Age(age)
	{
	}
	//显示函数
	void showPerson()
	{
		cout << "姓名:" << this->m_Name << endl;
		cout << "年龄:" << this->m_Age << endl;
	}

	T1 m_Name;
	T2 m_Age;
};


//2、参数模板化
template<class T1,class T2>
void printPerson004(Person4<T1, T2>&p)
{
	p.showPerson();
    cout << "T1的类型:" << typeid(T1).name() << endl;
	cout << "T2的类型:" << typeid(T2).name() << endl;
}
void test004()
{
	Person4<string, int>p("猪八戒", 123);
	printPerson004(p);

}

int main(void)
{
	test004();
	system("pause");
	return 0;
}

string名字有点长啊

class std::basic_string<char, struct std::char_traits<char>, class std::allocator<char> >

(3)整个类模板化 --- 将这个对象类型 模板化进行传递

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

//类模版
template<class T1,class T2>
class Person4
{
public:
	//构造函数
	Person4(T1 name,T2 age):m_Name(name),m_Age(age)
	{
	}
	//显示函数
	void showPerson()
	{
		cout << "姓名:" << this->m_Name << endl;
		cout << "年龄:" << this->m_Age << endl;
	}

	T1 m_Name;
	T2 m_Age;
};


//3、整个类模板化
template<class T>
void printPerson0004(T& p)
{
	p.showPerson();
	cout << "T的类型为:" << typeid(T).name() << endl;
}
void test0004()
{
	Person4<string, int>p("唐僧", 23);
	printPerson0004(p);
}
int main(void)
{
	test0004();
	system("pause");
	return 0;
}

总结:

  • 通过类模板创建的对象,可以有三种方式向函数中进行传参

  • 使用比较广泛是第一种:指定传入的类型

5、类模板与继承

当类模板碰到继承时,需要注意一下几点:

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

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

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

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

//类模版与继承
template<class T>
class Base
{
public:
	T m;
};

class Son :public Base
{

};


int main(void)
{


	system("pause");
	return 0;
}

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

//类模版与继承
template<class T>
class Base
{
public:
	T m;
};

//class Son :public Base              错误,必须要知道父类中T的类型
class Son:public Base<int>
{

};

void test05()
{
	Son son;
}

int main(void)
{


	system("pause");
	return 0;
}

如果想灵活指定父类中的T类型,子类也需要变模版

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

//类模版与继承
template<class T>
class Base
{
public:
	T m;
};


//如果想灵活指定父类中的T类型,子类也需要变模版
template<class T1,class T2>
class Son05 :public Base<T2>
{
public:
    Son05()
	{
		cout << "T1的类型:" << typeid(T1).name() << endl;
		cout << "T2的类型:" << typeid(T2).name() << endl;
	}

	T1 s;
};

void test005()
{
	Son05<int, char>s2;
}

int main(void)
{
	test005();

	system("pause");
	return 0;
}

总结:如果父类是类模板,子类需要指定出父类中T的数据类型

 

 

未完待续......

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【c++】类模版 的相关文章

随机推荐

  • 笔试算法题

    转自 http www cnblogs com xwdreamer archive 2011 12 13 2296910 html 1 把二元查找树转变成排序的双向链表 题目 输入一棵二元查找树 将该二元查找树转换成一个排序的双向链表 要求
  • 【TVM系列二】TVM介绍

    文章同步更新在公众号 AIPlayer 欢迎扫码关注 共同进步 目录 一 TVM的工作流程 1 整体流程 2 关键数据结构 3 Transformations 4 搜索空间和基于机器学习的转换 5 目标代码转化 二 逻辑架构组件 三 运行T
  • Android图形显示系统4 图像生产者(下)

    一 概述 在上一篇文章 Android图形显示系统2 图像消费者 中 我们详细地讲解了图像消费者 我们已经了解了 Android 中的图像元数据是如何被 SurfaceFlinger HWComposer 或者 OpenGL ES 消费的
  • 传统企业数字化转型难点有哪些?传统企业数字化转型战略方向

    互联网时代下 市场发展瞬息万变 企业数字化转型迫在眉睫 如何做好数字化转型 需要从以下这几个方面出发 1独立不孤立 企业需要积极主动加强对于数字化转型的认知 理解数字化转型的价值所在 开利网络认为 企业数字化转型首先是观念上的转换 通过贯彻
  • MATLAB生成单位矩阵、三角矩阵、零矩阵、1矩阵

    单位矩阵 eye m n 稀疏单位矩阵 speye m n ps I speye 1000 构成 1000 1000 单位矩阵的稀疏表示形式 它只需要大约 16 KB 的存储 这与 I sparse eye 1000 1000 的最终结果相
  • 概率论知识回顾(十七):方差

    概率论知识回顾 十七 重点 方差 知识回顾用于巩固知识和查漏补缺 知识回顾步骤 查看知识回顾中的问题 尝试自己解答 自己解答不出来的可以查看下面的知识解答巩固知识 对知识解答有疑问的 说明有关这一点的知识或者公式没有理解透彻或者没有记住 要
  • Win11 VSCode远程连接WSL2数据库

    首先 在VSCode中打开远程连接 可能会提示远程连接失败 无法连接到远程扩展主机服务器 错误 websocket close with status code 1006 这时启动wsl2 终端输入 vim etc ssh sshd con
  • CTFHub

    0x00 前言 CTFHub 专注网络安全 信息安全 白帽子技术的在线学习 实训平台 提供优质的赛事及学习服务 拥有完善的题目环境及配套 writeup 降低 CTF 学习入门门槛 快速帮助选手成长 跟随主流比赛潮流 0x01 题目描述 S
  • 单片机毕设选题 - 基于STM32自行车智能无线防盗报警器 -物联网 单片机 嵌入式

    hr style border solid width 100px height 1px color 000000 size 1 quot 0 前言 这两年开始毕业设计和毕业答辩的要求和难度不断提升 传统的毕设题目缺少创新和亮点 往往达不到
  • k8s_day01_01

    k8s day01 01 1 it发展趋势 it 的发展趋势中 我们最早的资源粒度从最早的物理机时代 到达十年之前的 kvm 还有xen 为代表的虚拟化代表的虚拟机时代 那个时候 VMware是如日中天的时期 vmware 以产品众多且成熟
  • 【安全知识】——如何绕过cdn获取真实ip

    作者名 白昼安全 主页面链接 主页传送门 创作初心 以后赚大钱 座右铭 不要让时代的悲哀成为你的悲哀 专研方向 web安全 后渗透技术 每日鸡汤 现在的样子是你想要的吗 cdn简单来说就是 通过不同地理位置的缓存来加快访问速度 所以我们有可
  • centos7离线升级gcc到9.3.1,解决redis6安装失败

    我们在安装Redis6的时候会编译出错 大概率是因为centos7的gcc版本 centos7的默认版本是4 8 5 需要将gcc版本升级到9 如果服务器是互联网环境 可以直接通过yum命令升级 yum y install centos r
  • MFC多字节和宽字节转换方式

    第一种转换 代码中可以直接用宏定义转换 可以使用 L 或者 T 但是对于传过来的值 就不能这样了 需要写函数转换 第二种转换 必须在一个函数中执行 否则上一次调用并不会释放栈中的空间 要直到函数结束才会释放空间 测试是否释放内存空间可以使用
  • 单片机——PWM调光工作原理

    前言 如果只用单片机做一个调光系统 pwm是可以实现的 但是如果有其它的功能 比如传感器要检测 显示屏显示数据等等功能 就不推荐了 其它函数一多 定时器的时间又比较短 以至于单片机大多数时间都用在定时中断函数里去了 处理其它函数的时间太少
  • 京东云鼎服务器系统时间问题-时间戳参与与服务器时间差异大于设定值

    业务背景 目前业务对接了各大电商平台的订单 按照规定京东需要入鼎进行调用jos接口来拉取订单 相当于与订单API之间多一个应用中转 如图 该文章暂时不讨论对接的细节 后面打算出个专题文章细说各大电商平台的对接 目前好像比较少这个业务的分享
  • ios 无法发起ajax请求,PhoneGap的iOS的Ajax请求无法完成(Phonegap iOS ajax request

    请阅读更新这个答案在底部 原来的答案 我已经找到了问题所在 并设法得到基本的认证工作 问题是 Web服务器期待基本身份验证的细节与请求一起发送先发制人 要做到这一点使用 头 的jQuery AJAX的特性如下图所示 ajax type GE
  • 【debug】error: subprocess-exited-with-error

    在安装Python的某个三方包时 出现了下面的报错方式 error subprocess exited with error 解决办法 解决方案重新安装importlib metadata pip install importlib met
  • 经典面试题-大厂SQL题目

    1 如何用一个SQL找出部门下所有员工的平均工资大于某个数 例如20000元 的所有部门 正确答案 select depno avg sal as avgsal from emp group by depno having avgsal g
  • 使用python编写脚本测试目标主机的TCP端口连通性

    使用Python的Socket模块的connect 函数来尝试连接目标主机的特定端口 如果连接成功 则说明该端口是打开的 否则 该端口是关闭的 下面是一个示例脚本 可以检测目标IP的22端口是否开启 import socket def ch
  • 【c++】类模版

    1 类模板语法 类模板作用 建立一个通用类 类中的成员 数据类型可以不具体制定 用一个虚拟的类型来代表 语法 template