31 C++ 模版和泛型

这篇具有很好参考价值的文章主要介绍了31 C++ 模版和泛型。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前提

我们先来看一类问题,如下的三个方法能否换成一个方法呢?

这就是模版的来历。

int funcadd(int a, int b) {
	return a + b;
}
double funcadd(double a, double b) {
	return a + b;
}

float funcadd(float a,float b) {
	return a + b;
}

模版的概念

所谓泛型编程,是以独立于 任何 特定类型的方式编写代码

这意味着,我们在声明或者定义的时候,不会指定具体的类型。

但是在使用的时候,需要指定具体的类型或者值

模版是泛型编程的基础公式。

模版一般分为 函数模版 和 类模版

函数模版定义:

template <class T1,class T2>
T1 func88(T1 a, T2 b) {
    return a + b;
}

函数模版的定义通常都是在.h文件中

函数模版的调用

int a =10; int b =20;

func88(a,b);

函数模版 的常用方式一:

定义的时候:使用 如下的代码,告知C++编译器:"T 是一种类型,不要报错".

在编译阶段:当编译器看到有函数模版的具体调用的时候,函数模版才会生成具体的函数;

如果没有调用,编译器则不会生成具体的函数;

template <typename T>

或者

template <class T>

函数模版

//如上的三个函数,能写成一个函数会更好,这就是模版存在的意义。
template <class T>
T funcadd(T a, T b) {
	return a + b;
}

void main() {
	int a = 1;
	int b = 2;

	cout << funcadd<int>(a ,b) << endl;

	double a1 = 9.9;
	double b1 = 89.9;
	cout << funcadd(a1, b1) << endl;
}
template <class T1,class T2>
T1 func88(T1 a, T2 b) {
	return a + b;
}


使用:
	int a2 = 10;
	double b2 = 89.8;
	int a3 = func88(a2,b2);
	cout << a3 << endl;

	int a4 = 1000;
	int a5 = func88(a2, a4);//T1 和 T2 可以一样
	cout << a5 << endl;

函数模版的不常用方式二:

直接在template 上定义了具体的类型。

template<int a1 , int a2>
int func89(){
    return a1 + a2;
}

template<int a1 , int a2>
int func89(){
	return a1 + a2;
}

void main() {
	cout<<func89<10, 20>()<<endl;
	int aa = 10;
	//cout << func89<aa, 20>() << endl;//会有build error。这里其实没有理解,理论上应该知道是啥类型才对
}

类模版定义:

类模版的定义通常都是在.h文件中,

且必须要有类的全部信息 --- 包括类模版中的成员函数的函数体。

和函数模版一样,编译器在实例化模版类时候,编译器就会生成一个具体的类文章来源地址https://www.toymoban.com/news/detail-782616.html

//类模版
template <class T, class T1>
class Teacher89 {

typedef T1* myiterator;
public :
	T m_age;
	myiterator iter;//迭代器

public:
	Teacher89() {
		cout << "空的 构造函数" << endl;
	}

	Teacher89(T age, T1 iter):m_age(age){
		cout << "有两个参数的 构造函数" << endl;
		this->iter = &iter;
	}

//类模版中的成员函数 函数体 写在类模版中,会被声明为inline函数,
	int getInt() {
		return 10;
	}
//类模版中的成员函数 函数体 写在类模版外,只是在类模版中声明
	double getdouble();


//类模版中成员函数如果返回值是 一个模版类行,函数体写在类模版外,只是在类模版中声明
	myiterator getInterator();

//注意的是:即使实例化模版之后,如果没有任何成员函数被使用,类模版中的成员函数也不会被实例化。
//但是当只要有一个 成员函数被使用,那么所有的类成员函数模版都会被实例化

};
template <class T, class T1>
double Teacher89<T, T1>::getdouble() {
	return 89.9;
}



template<typename T, class T1> //typename Teacher89<T, T1 >::myiterator 声明这玩意是个返回类型
typename Teacher89<T, T1 >::myiterator Teacher89<T, T1>::getInterator(){
	return Teacher89<T, T1>::iter;
}

void main() {
	cout << "断点" << endl;
	Teacher89<int, string *> t89; //模版类的实例化
	//注意的是:Teacher89是类的模版名,Teacher89<int, string *>才是类型名。
	//所以,一个实例化的类型,总会用尖括号<>包含着模版参数

	string abc("nihao");
	Teacher89<int, string > t891(80,abc);//模版类的实例化
	cout << t891.getInt() << endl;
	cout << t891.getdouble() << endl;
	cout << t891.getInterator() << endl; // 打印出来的是地址:0x00000077676ffbb8,debug看到在构造函数中 :this->iter = 0x00000077676ffbb8 "nihao"
	cout << "---" << endl;
	cout << *(t891.getInterator()) << endl; //但是这个打印不出来nihao,啥都打印不出来,原因未知???
}

到了这里,关于31 C++ 模版和泛型的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • go语言的反射和泛型

    反射可以在程序的运行时获取变量的各种信息。Go语言中光反射在 reflect 包下。 http://c.biancheng.net/view/4407.html Go语言中通过 断言 转化为指定类型。 但是这并不具有通用性,通过断言的判断必须是已有定义的类型,未定义的就不可用,因此没有通用性。泛型就是来解决这一问题

    2024年02月10日
    浏览(37)
  • java学习——ArrayList和泛型(学习记录)

    学习资料来自菜鸟教程 ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。 ArrayList 继承了 AbstractList ,并实现了 List 接口。 ArrayList 类位于 java.util 包中,使用前需要引入它,语法格式如下: E: 泛型数据类型,

    2024年02月06日
    浏览(52)
  • Java重修第八天—枚举和泛型

    通过学习本篇文章可以掌握如下知识 1、枚举 2、泛型 枚举是一种 特殊类 枚举类的格式: 为什么说枚举是一个特殊类,定义一个简单的枚举如下: 将其编译成class文件后,使用IDEA打开, 结果如下 :可以看出枚举类A有私有构造器。 枚举类的第一行只能罗列一些名称, 这些

    2024年01月17日
    浏览(28)
  • 【Rust】——提取函数消除重复代码和泛型

    🎃个人专栏: 🐬 算法设计与分析:算法设计与分析_IT闫的博客-CSDN博客 🐳Java基础:Java基础_IT闫的博客-CSDN博客 🐋c语言:c语言_IT闫的博客-CSDN博客 🐟MySQL:数据结构_IT闫的博客-CSDN博客 🐠数据结构:​​​​​​数据结构_IT闫的博客-CSDN博客 💎C++:C++_IT闫的博客-CSDN博

    2024年03月26日
    浏览(31)
  • 数据结构(Java实现)-包装类和泛型

    包装类 在Java中,由于基本类型不是继承自Object,为了在泛型代码中可以支持基本类型,Java给每个基本类型都对应了 一个包装类型。 基本数据类型和对应的包装类 装箱和拆箱 装箱操作,新建一个 Integer 类型对象,将 i 的值放入对象的某个属性中 拆箱操作,将 Integer 对象中

    2024年02月11日
    浏览(30)
  • Armadillo:矩阵类、向量类、Cube类和泛型类

    密集矩阵的类,其元素按列优先顺序存储(即逐列) 根矩阵类是 Mattype ,其中 type 是以下项之一: float 、 double 、 std::complexfloat 、 std::complexdoubleshort 、 int 、 long 和无符号的 short 、 int 、 long 为方便起见,定义了以下 typedef: 在本文档中,为了方便起见,使用了垫子类型;

    2024年04月15日
    浏览(30)
  • Swift-31-泛型和类型操作

    Swift泛型(generics) 让我们写出的类型和函数可以使用对于我们或编译器都未知的类型。 很多内建类型(包括可空类型、数组和字典)都是用泛型实现的,比如数组和一些集合就是用泛型方式来实现的。 一种运行时进行类型检查的技术,效率高但是不安全。在swift中泛型可用于结构

    2024年04月28日
    浏览(22)
  • 【C++】详细介绍模版初阶—函数模版、类模板

    ヾ(๑╹◡╹)ノ\\\" 人总要为过去的懒惰而付出代价 ヾ(๑╹◡╹)ノ\\\" 泛型编程 :编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。【不是针对某种类型】 template模版 template class T template typename T 模版的参数学习,可以类比函数参数。 模版参数

    2024年02月11日
    浏览(29)
  • C++模版初阶

    如下的交换函数中,它们只有类型的不同,应该怎么实现一个通用的交换函数呢? 使用函数重载虽然可以实现,但是有一下几个不好的地方:         1. 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增加对应的函数;       

    2024年02月05日
    浏览(31)
  • 【C++】模版初阶

    目录 泛函编程 函数模版 概念 格式 原理 实例化 模版函数的匹配原则 类模板 定义格式 如何实现一个通用的交换函数呢? 使用函数重载虽然可以实现,但是有几个不好的地方: 1. 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增加对

    2024年02月19日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包