C++类模板

news2025/1/12 0:51:06

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

类模板作用:

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

语法:

template<typename T>
/*
template  ---  声明创建模板

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

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

#include <string>
#include<iostream>
using namespace std;
//类模板
template<class NameType, class AgeType>
class Person
{
public:
	Person(NameType name, AgeType age)
	{
		this->mName = name;
		this->mAge = age;
	}
	void showPerson()
	{
		cout << "name: " << this->mName << " age: " << this->mAge << endl;
	}
public:
	NameType mName;
	AgeType mAge;
};

void test01()
{
	// 指定NameType 为string类型,AgeType 为 int类型
	Person<string, int>P1("李明", 123);
	P1.showPerson();
}

int main() {

	test01();

	system("pause");

	return 0;
}

类模板与函数模板区别主要有两点:
        1. 类模板没有自动类型推导的使用方式(编译器不能自动识别参数类型)
        2. 类模板在模板参数列表中可以有默认参数

template<class NameType, class AgeType = int>

可以直接指定参数类型,下面代码中将默认AgeType是int型

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

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

class Person1
{
public:
	void showPerson1()
	{
		cout << "Person1 show" << endl;
	}
};

class Person2
{
public:
	void showPerson2()
	{
		cout << "Person2 show" << endl;
	}
};

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

	//类模板中的成员函数,并不是一开始就创建的,而是在模板调用时再生成

	void fun1() { obj.showPerson1(); }
	void fun2() { obj.showPerson2(); }

};

void test01()
{
	MyClass<Person1> m;

	m.fun1();

	//m.fun2();//编译会出错,说明函数调用才会去创建成员函数
}


int main() {

	test01();
	system("pause");

	return 0;
}

类模板对象做函数参数:

类模板实例化出的对象,向函数传参的方式

一共有三种传入方式:

1. 指定传入的类型   --- 直接显示对象的数据类型
2. 参数模板化           --- 将对象中的参数变为模板进行传递
3. 整个类模板化       --- 将这个对象类型 模板化进行传递

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


template<class NameType, class AgeType = int>
class Person
{
public:
	Person(NameType name, AgeType age)
	{
		this->mName = name;
		this->mAge = age;
	}
	void showPerson()
	{
		cout << "name: " << this->mName << " age: " << this->mAge << endl;
	}
public:
	NameType mName;
	AgeType mAge;
};

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

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

//3、整个类模板化
template<class T>
void printPerson3(T& p)
{
	cout << "T的类型为: " << typeid(T).name() << endl;
	p.showPerson();

}
void test03()
{
	Person <string, int >p("唐僧", 30);
	printPerson3(p);
}

int main() {

	test01();
	test02();
	test03();

	system("pause");

	return 0;
}

 第一种用的比较广泛

类模板的继承:

#include<iostream>
using namespace std;
#include<string>
template<class T>
class Base
{
	T m;
};
//class Son:public Base  //错误,c++编译需要给子类分配内存,必须知道父类中T的类型才可以向下继承
class Son :public Base<int> //必须指定一个类型
{
};
void test01()
{
	Son c;
}

//类模板继承类模板 ,可以用T2指定父类中的T类型
template<class T1, class T2>
class Son2 :public Base<T2>
{
public:
	Son2()
	{
		cout << typeid(T1).name() << endl;
		cout << typeid(T2).name() << endl;
	}
};

void test02()
{
	Son2<int, char>child ;
}


int main() {

	test01();
	test02();

	system("pause");

	return 0;
}

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

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

类内实现:

template<typename T1, typename T2>
class Person
{
public:
	Person(T1 name, T2 age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}
 
	void showPerson()
	{
		cout << "姓名:" << this->m_Name << ", 年龄:" << this->m_Age << endl;
	}
 
private:
	T1 m_Name;
	T2 m_Age;
};

 类外实现:

template<class T1, class T2>
class Person {
public:
	//成员函数类内声明
	Person(T1 name, T2 age);
	void showPerson();

public:
	T1 m_Name;
	T2 m_Age;
};

//构造函数 类外实现
template<class T1, class T2>
Person<T1, T2>::Person(T1 name, T2 age)//声明作用域
 {
	this->m_Name = name;
	this->m_Age = age;
}

//成员函数 类外实现
template<class T1, class T2>
void Person<T1, T2>::showPerson() {
	cout << "姓名: " << this->m_Name << " 年龄:" << this->m_Age << endl;
}

void test01()
{
	Person<string, int> p("李明", 18);
	p.showPerson();
}

int main() {

	test01();

	system("pause");

	return 0;
}

类模板中成员函数类外实现时,需要加上模板参数列表

类模板和友元:

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

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

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

//2、全局函数配合友元  类外实现 - 先做函数模板声明,下方在做函数模板定义,在做友元
template<class T1, class T2> class Person;

//如果声明了函数模板,可以将实现写到后面,否则需要将实现体写到类的前面让编译器提前看到
//template<class T1, class T2> void printPerson2(Person<T1, T2> & p); 

template<class T1, class T2>
void printPerson2(Person<T1, T2> & p)
{
	cout << "类外实现 ---- 姓名: " << p.m_Name << " 年龄:" << p.m_Age << endl;
}

template<class T1, class T2>
class Person
{
	//1、全局函数配合友元   类内实现
	friend void printPerson(Person<T1, T2> & p)
	{
		cout << "姓名: " << p.m_Name << " 年龄:" << p.m_Age << endl;
	}


	//全局函数配合友元  类外实现
	friend void printPerson2<>(Person<T1, T2> & p);

public:

	Person(T1 name, T2 age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}


private:
	T1 m_Name;
	T2 m_Age;

};

//1、全局函数在类内实现
void test01()
{
	Person <string, int >p("Tom", 20);
	printPerson(p);
}


//2、全局函数在类外实现
void test02()
{
	Person <string, int >p("Jerry", 30);
	printPerson2(p);
}

int main() {

	//test01();

	test02();

	system("pause");

	return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/489475.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深入解析PyTorch中的模型定义:原理、代码示例及应用

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

【基础算法】大数运算问题

&#x1f339;作者:云小逸 &#x1f4dd;个人主页:云小逸的主页 &#x1f4dd;Github:云小逸的Github &#x1f91f;motto:要敢于一个人默默的面对自己&#xff0c;强大自己才是核心。不要等到什么都没有了&#xff0c;才下定决心去做。种一颗树&#xff0c;最好的时间是十年前…

Python高光谱遥感数据处理与机器学习(最新的技术突破讲解和复现代码)

将高光谱技术与Python编程工具结合起来&#xff0c;聚焦高频技术难点&#xff0c;明确开发要点&#xff0c;快速复现高光谱数据处理和分析过程&#xff0c;并对每一行代码进行解析&#xff0c;对学习到的理论和方法进行高效反馈。实践篇&#xff0c;通过高光谱矿物识别&#xf…

了解这个项目进度跟踪管理工具,轻松掌握项目进度

白天开会晚上干活的PM和战场上的将军没有区别&#xff0c;产品研发如同组团杀敌&#xff0c;团队配合最为重要。Zoho Projects项目管理工具&#xff0c;适用于各种规模和需求的公司。 一、需求管理 在项目中&#xff0c;我们使用它Zoho收集整理各方反馈&#xff0c;快速处理工单…

自媒体达人养成计划(ChatGPT+new bing)

本节课我们来探索如何使用GPT帮助我们成为自媒体达人&#xff0c;快速赚到一个小目标&#xff01;在此之前&#xff0c;我们需要先做些准备工作~ 首先是平台选取&#xff0c;写文章第一件事就是要保证内容的有效性和准确性&#xff0c;不然就成为营销号了嘛&#xff0c;所以我…

5---最长回文字串

给你一个字符串 s&#xff0c;找到 s 中最长的回文子串。 如果字符串的反序与原始字符串相同&#xff0c;则该字符串称为回文字符串。 示例 1&#xff1a; 输入&#xff1a;s “babad” 输出&#xff1a;“bab” 解释&#xff1a;“aba” 同样是符合题意的答案。 示例 2&…

改进沙猫群优化算法(ISCSO)-附代码

改进沙猫群优化算法(ISCSO) 文章目录 改进沙猫群优化算法(ISCSO)1.沙猫群优化算法2. 改进沙猫群优化算法2.1 混沌映射初始化2.2 引入互利共生策略2.3 引入莱维飞行策略 3.实验结果4.参考文献5.Matlab代码6.Python代码 摘要&#xff1a;对沙猫群优化算法进行改进。在改进的沙猫群…

Vue.js 教程---菜鸟教程

文章目录 Vue.js 教程Vue.js 安装Vue.js 起步Vue.js 模板语法插值指令用户输入过滤器缩写 Vue.js 条件语句Vue.js 循环语句Vue.js 计算属性Vue.js 监听属性Vue.js样式绑定 Vue.js 教程 本教程主要介绍了 Vue2.x 版本的使用 第一个实例&#xff1a; <body> <div id&…

Linux 信号学习

Linux 信号学习 信号量的基本概念信号产生的条件信号如何被处理信号的异步特质 信号的分类可靠信号/不可靠信号实时信号/非实时信号 常见信号与默认行为信号处理signal() 函数sigaction()函数 向进程发送信号kill() 函数raise() 函数 alarm()和pause()函数alarm() 定时函数paus…

玩转传感器----理解时序和数据采集(DHT11)

该文章以DHT11模块进行分析 目录 1.模块复位&#xff08;时序图&#xff09; 2.DHT11的应答信号 3.读取1bit数值&#xff08;比较高电平的时间是否大于40us&#xff09; 4.读取一个字节 5.把读取的字节放入单片机 6. 寄存器设置IO口方向 1.模块复位&#xff08;时序图&a…

22.Java多线程

Java多线程 一、进程和线程 进程是程序的一次动态执行过程&#xff0c;它需要经历从代码加载&#xff0c;代码执行到执行完毕的一个完整的过程&#xff0c;这个过程也是进程本身从产生&#xff0c;发展到最终消亡的过程。多进程操作系统能同时达运行多个进程&#xff08;程序…

使用Python接口自动化测试post请求和get请求,获取请求返回值

目录 引言 请求接口为Post时&#xff0c;传参方法 获取接口请求响应数据 引言 我们在做python接口自动化测试时&#xff0c;接口的请求方法有get,post等&#xff1b;get和post请求传参&#xff0c;和获取接口响应数据的方法&#xff1b; 请求接口为Post时&#xff0c;传参方法…

C++系列二:数据类型

C数据类型 1. 原始类型2. 复合类型3. 类型转换3.1 隐式类型转换3.2 显式类型转换 4. 总结&#xff08;手稿版&#xff09; 1. 原始类型 C 中的原始类型包括整型&#xff08;integral types&#xff09;、浮点型&#xff08;floating-point types&#xff09;、字符型&#xff…

涨薪60%,从小厂逆袭,坐上美团技术专家(面经+心得)

前言 大多数情况下&#xff0c;程序员的个人技能成长速度&#xff0c;远远大于公司规模或业务的成长速度。所以&#xff0c;跳槽成为了这个行业里最常见的一个词汇。 实际上&#xff0c;跳槽的目的无非是为了涨薪或是职业发展&#xff0c;我也不例外。普通本科毕业后&#xf…

计算机网络基础知识(一)计算机发展史、网络设备、网络结构及拓扑

文章目录 01 | 网络设备02 | 网络结构 && 拓扑 网络发展史可以追溯到20世纪60年代&#xff0c;当时美国国防部高级研究计划署&#xff08;ARPA&#xff09;启动了一个名为 ARPANET 的项目&#xff0c;旨在建立军事目的的分布式通信网络&#xff0c;使得网络中的任何一台…

【redis】redis红锁Redlock算法和底层源码分析

【redis】redis红锁Redlock算法和底层源码分析 文章目录 【redis】redis红锁Redlock算法和底层源码分析前言一、当前代码为8.0版&#xff0c;接上一步分布式锁的主要考点lock加锁关键逻辑unlock解锁关键逻辑 二、redis分布式锁-Redlock红锁主页说明:目前所写的分布式锁还有什么…

c++自学笔记(陆续更新)

本笔记为从菜鸟教程边学边记录的笔记---》C 教程 | 菜鸟教程 面向对象程序设计 封装&#xff08;Encapsulation&#xff09;&#xff1a;封装是将数据和方法组合在一起&#xff0c;对外部隐藏实现细节&#xff0c;只公开对外提供的接口。这样可以提高安全性、可靠性和灵活性。…

C语言入门教程||C语言 头文件||C语言 强制类型转换

C语言 头文件 头文件是扩展名为 .h 的文件&#xff0c;包含了 C 函数声明和宏定义&#xff0c;被多个源文件中引用共享。有两种类型的头文件&#xff1a;程序员编写的头文件和编译器自带的头文件。 在程序中要使用头文件&#xff0c;需要使用 C 预处理指令 #include 来引用它…

USART串口接收

文章目录 运行环境&#xff1a;1.1 串口接收代码分析1)开启接收中断和空闲中断2)接收存储变量声明和定义3)中断处理函数 2.1实验效果 运行环境&#xff1a; ubuntu18.04.melodic 宏基暗影骑士笔记本 stm32f427IIH6 stlink 9-24v可调电源 usb转串口 杜邦线转4pin 1.1 串口接收…

Python | 人脸识别+活体检测+背景模糊+关键点检测系统(Face_Recognition+dlib+OpenCV+MediaPipe+PyQt)

本博客为人脸识别系统项目简介 项目GitHub完整源代码地址&#xff1a; 一、运行环境 本系统能够运行在基于PC操作系统Windows环境下&#xff0c;要求Windows操作系统安装Python 3.9 及以上环境&#xff0c;且已安装MySQL数据库。 Python3.9 安装&#xff1a;Python 3.9安装教程…