首页 > 编程语言 >C++模版简单认识与使用

C++模版简单认识与使用

时间:2024-04-06 19:31:32浏览次数:27  
标签:调用 认识 模版 C++ int Add right left

目录

前言:

1.泛型编程

2.函数模版

3.类模版

为什么要有类模版?使用typedef不行吗?

类模版只能显示实例化:

注意类名与类型的区别:

注意类模版最好不要声明和定义分离:

总结:


前言:

正如标题而言,这里只是对模版的简单认识与使用,方便后面博客介绍stl中一些容器的实现,更复杂详细的模版相关的内容将会在模版进阶中介绍。

1.泛型编程

编写与类型无关的通用代码,是代码复用的一种手段,模版是泛型编程的基础。

而模版又分为函数模版与类模版。

2.函数模版

template<class T>
void Swap(T& x, T& y)
{
	T tmp = x;
	x = y;
	y = tmp;
}


int main()
{
	int a = 1, b = 2;
	double c = 1.0, d = 2.0;
	
	Swap(a, b);
	Swap(c, d);

	return 0;
}

首先要注意第一点:

两次调用的Swap函数实际都不是同一个函数,第一是函数调用开辟的栈帧都不一样大,一个是int,一个是double;第二是汇编call的函数的地址也是不一样的。

这里的class可用typename替换,区别在后面的学习中会介绍。

 

补充一下库中的swap函数:

 

那模版参数是怎么识别不同的类型的呢?这就是模版的实例化,实际就是编译器帮你完成了这个工作,是隐式的实例化自动推演模版的类型。模版的实例化发生在编译时期,所以是在编译的时候根据类型推导生成的代码

那下面来看两个问题,首先第一个,传的模版参数不明确,会报错:

template<class T>
T Add(const T& left, const T& right)
{
	return left + right;
}


int main()
{
	int a = 1;
	double b = 1.1;
	Add(a, b);//报错

解决方法1:

强制转换类型,但是会丢失精度。

Add(a1,(int)d1);

 解决方法2:

使用显示实例化,其实经历了隐式类型转换:

cout<<Add<int>(a,b)<<endl;//实际b转int经过了隐式类型转换

问题2,这样的能同时存在吗:

int Add(int left, int right)
{
	return left + right;
}

template<class T>
T Add(const T& left, const T& right)
{
	return left + right;
}

template<class T1,class T2>
T1 Add(T1 left, T2 right)
{
	return left + right;
}


int main()
{
	int a = 1;
	double b = 1.1;
	Add(a, b);
}

首先,前两个能同时存在吗?答案是可以的,因为函数名的修饰规则可能不一样。

其次,调用的时候都传的类型是int类型,前两个应该谁先调用呢?答案是会调用第一个,因为第一个在编译是就确定了地址,直接就调用了,而第二个在编译时才根据类型推导生成对应的代码,也就是先要经历模版的实例化。

那如何就想调用模版呢?使用模版的显示实例化呗,Add<int>(a,b);

那在这3个模版中,传的类型不一样,会先去调用哪一个?答案是去调用第三个,编译器是聪明的,会去调用最合适最匹配的那一个;而如果没有第三个,对应的才会调用第二个。

 

3.类模版

格式就是:

template<class T1,class T2,...,class Tn>
class 类模版名
{
   //类成员定义
};

 

为什么要有类模版?使用typedef不行吗?

如果我们使用typedef,那第一类想要int,第二个类想要double,是不是还要再写两个类?所以就用到了类模版,但是还是调用了两个类,编译器帮你实现了:

注意类里面的构造函数new了,需要析构时delete,因为类的对象销毁会调用析构。

类模版只能显示实例化:

因为就算调用构造函数也传不到T的身上啊,并且传的值要怎么识别是T呢?

注意类名与类型的区别:
	vector<int> v1;

不加上模版参数只是类名,加上才是类型。

注意类模版最好不要声明和定义分离:

(这里指的是头文件放类模版的定义,.cpp文件放声明,分文件的声明定义分离),否则会出现链接错误(虽然有解决方式,但是还是不建议,至于为什么到模版进阶会介绍)。

如果想要类模版的声明和定义分离,目前可以放到在同一个文件里面,然后可以在类里面声明,在类外面定义(拿析构函数举例),注意类模版的定义要写在这个类的下面,不然找不到。但是还是不建议分开写,容易出错:

class Vector
{
public:
	Vector(int capacity=4)
	{
		_pDate = new T[capacity];
		_size = _capacity = 0;
	}
	~Vector();

private:
	T* _pDate;
	int _size;
	int _capacity;
};

template<class T>
Vector<T>::~Vector()
{
	delete[] _pDate;
	_pDate = nullptr;
	_size = _capacity = 0;
}


int main()
{
	Vector<int> v1;
	return 0;
}

 

总结:

本篇偏重基本的使用和注意事项,关于模版更进阶的到模版进阶篇再介绍。

标签:调用,认识,模版,C++,int,Add,right,left
From: https://blog.csdn.net/2301_79698419/article/details/137410351

相关文章

  • QT和C++排列组合
    界面比较简洁,如有需要请大家自行完善!!!头文件#pragmaonce#include<QtWidgets/QMainWindow>#include"ui_text.h"classtext:publicQMainWindow{  Q_OBJECTpublic:  text(QWidget*parent=nullptr);  ~text();  voidParseStringToVector(con......
  • 深入理解C++ lambda表达式:用法、特性与最佳实践
    文章目录一、引言1、lambda表达式的概念2、lambda表达式在C++中的重要作用3、lambda表达式的基本语法结构二、lambda表达式的核心特性1、捕获列表2、参数列表3、返回类型4、函数体5、multable关键字三、lambda表达式的进阶用法1、lambda表达式与STL算法的结合使用2、la......
  • C++11中auto与decltype的区别与联系深入解析
    文章目录一、引言二、auto关键字及其特性1、auto的基本定义与用途2、auto在类型推导中的应用3、auto的局限性及需要注意的问题三、decltype关键字及其特性1、decltype的基本定义与用途2、decltype在类型推导中的应用3、decltype的局限性及需要注意的问题四、auto与decl......
  • C++从入门到精通——类和对象(上篇)
    1.面向过程和面向对象初步认识C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。2.类的引入C语言中,结构体中只能定义变量,在C++中,结构体内不仅可以定义变量......
  • C++数据结构与算法——回溯算法组合问题
    C++第二阶段——数据结构和算法,之前学过一点点数据结构,当时是基于Python来学习的,现在基于C++查漏补缺,尤其是树的部分。这一部分计划一个月,主要利用代码随想录来学习,刷题使用力扣网站,不定时更新,欢迎关注!文章目录一、77.组合二、216.组合总和III三、17.电话号码的字......
  • C++ this指针的概念和使用
    this指针的概念:在C++中成员变量和成员函数是分开存储的。每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码。那么问题是:这一块代码是如何区分哪个对象调用自己的呢?c++通过提供特殊的对象指针,this指针,解决上述问题。关键:this指针指向......
  • C++中拷贝构造函数调用时机——学习记录
    拷贝构造函数调用时机:C++中拷贝构造函数调用时机通常有三种情况使用一个已经创建完毕的对象来初始化一个新对象值传递的方式给函数参数传值以值方式返回局部对象问题描述在黑马C++课程上学习时发现,第三种情况:以值方式返回局部对象时会不会调用构造函数。对比后发现,黑......
  • 关于学术论文的一些认识
    1.什么是核心期刊、SCI核心期刊通常是指在特定学科领域内具有一定学术影响力和水平的期刊,经过权威机构认定,并受到学术界和科研机构的认可和重视。这些期刊通常具有严格的审稿制度、高质量的论文和较高的引用率。SCI(ScienceCitationIndex)是科学引文索引,是由美国科学信息研究所......
  • socket编程——C++实现基于UDP协议的简单通信(含详解)
    文章后面有代码,可以直接复制在VisualStudio2022中运行(注意:必须是两个项目,客户端服务端各一个,连接在同一网络中,先运行服务端,并且客户端数据发送的目标IP要改为你服务端的IP)目录前言帮助文档一、UDP通信框架1.服务端2.客户端二、服务端实现1.加载库(WSAStartup函数)......
  • [C++] 小游戏 斗破苍穹2.8.1版本 zty出品
    前言大家好,今天zty带来的是首次增加调试角色的版本,2.8.1版本主要更新了调试角色(感觉没啥用)。先赞后看 养成习惯点赞过100一天更3次正文#include<stdio.h>#include<iostream>#include<ctime>#include<bits/stdc++.h>#include<time.h>//suiji#include<windows.h>/......