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

深圳方维网站建设销售app软件大概需要多少钱

深圳方维网站建设,销售app软件大概需要多少钱,网站开发先学前端还是后端,可视化小程序开发工具今天我们来学习C中模板的学习。但是模板是C中比较难的部分,因此本节我们直接出相对比较初阶的部分。 目录 泛型编程 函数模板 函数模板格式 函数模板的原理 函数模板的特性 函数模板的实例化 模板参数的匹配原则 类模板 类模板定义格式 类模板实例化 泛型…

       今天我们来学习C++中模板的学习。但是模板是C++中比较难的部分,因此本节我们直接出相对比较初阶的部分。

目录

泛型编程

函数模板 

函数模板格式

函数模板的原理

函数模板的特性

函数模板的实例化

模板参数的匹配原则

类模板

        类模板定义格式

类模板实例化


泛型编程

        引例:写一个通用类型的交换函数

        如果用函数重载来写,就是这样

void swap(int& a, int& b)
{int temp = a;a = b;b = temp;
}
void swap(double& a, double& b)
{double temp = a;a = b;b = temp;
}
void swap(char& a, char& b)
{char temp = a;a = b;b = temp;
}

        这样当然也是可以。 但是显然我们发现,函数重载写起来十分的麻烦。每次出现一个类型都要写一个函数重载,并且很危险,一旦一个出错了所有重载都错了。

        那么有没有一个办法能更简便呢?答案是有的,C++为咯应对这个情况有一个东西:模板

        模板的作用就是告诉编译器一个模板,让编译器根据不同的类型利用该模板生成代码。

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

        模板分为函数模板和类模板 

        

函数模板 

        函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本

函数模板格式

        语法结构如下:

//模板
template<class T> 
template<typename A>

        注意:typename是用来定义模板参数的关键字,也可以使用class来定义(但是切记不要用struct代替class) 

总结为

//模板
template<typename T1, typename T2,...... typename Tn>
返回值类型    函数名(参数列表)
{}

因此交换数据的函数我们可以这样改写:

//模板
template<typename T>
void swap(T& a, T& b)
{T temp = a;a = b;b = temp;
}
int main()
{int i = 1, j = 2;double d1 = 3.14, d2 = 2.71;char c1 = 'a', c2 = 'b';swap(i,j);swap(d1,d2);swap(c1,c2);cout << "i=" << i << " j=" << j << endl;cout << "d1=" << d1 << " d2=" << d2 << endl;cout << "c1=" << c1 << " c2=" << c2 << endl;return 0;
}

结果如下:

 

函数模板的原理

        函数模板是一个蓝图,本身不是函数,是编译器用使用方式产生特定具体类型函数的模板,所以模板就是将本来我们要做的事情交给了编译器去做

        在编译器阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用。例如double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码。

函数模板的特性

        上面的交换代码中,是不可以这么写的。        

swap(i, d1); //编译错误,类型不匹配

         我们可以有以下几种方法处理:类型强转和实例化

函数模板的实例化

        用不同类型的参数使用函数模板的时候,成为函数模板的实例化。函数模板实例化分为隐式实例化显式实例化

        1.隐式实例化:让编译器根据实参推演模板参数的实际类型

#include <iostream>
using namespace std;
//模板
template<typename T>
void swap(const T& a, const T& b)
{T temp = a;a = b;b = temp;
}
int main()
{int i = 1, j = 2;double d1 = 3.14, d2 = 2.71;char c1 = 'a', c2 = 'b';swap(i,j);swap(d1,d2);swap(c1,c2);cout << "i=" << i << " j=" << j << endl;cout << "d1=" << d1 << " d2=" << d2 << endl;cout << "c1=" << c1 << " c2=" << c2 << endl;//隐式实例化swap((double)i, d1); return 0;
}

        2.显式实例化

#include <iostream>
using namespace std;
//模板
template<typename T>
void swap(const T& a, const T& b)
{T temp = a;a = b;b = temp;
}
int main()
{int i = 1, j = 2;double d1 = 3.14, d2 = 2.71;char c1 = 'a', c2 = 'b';swap(i,j);swap(d1,d2);swap(c1,c2);cout << "i=" << i << " j=" << j << endl;cout << "d1=" << d1 << " d2=" << d2 << endl;cout << "c1=" << c1 << " c2=" << c2 << endl;//显式实例化swap<int>(i, d1); return 0;
}

模板参数的匹配原则

        1.一个非模板函数可以和一个同名函数模板同时存在,而且函数模板还可以被实例化为这个非模板函数

#include <iostream>
using namespace std;
//专门的函数
void swap(int& a, int& b)
{int temp = a;a = b;b = temp;
}
//函数模板
template<typename T>
void swap(const T& a,const T& b)
{T temp = a;a = b;b = temp;
}
int main()
{int i = 1, j = 2;double d1 = 3.14, d2 = 2.71;char c1 = 'a', c2 = 'b';swap(i,j);//与非模板函数匹配,编译器无需优化swap(d1,d2);swap(c1,c2);cout << "i=" << i << " j=" << j << endl;cout << "d1=" << d1 << " d2=" << d2 << endl;cout << "c1=" << c1 << " c2=" << c2 << endl;swap(i,d1);//调用编译器优化的模板函数return 0;
}

        2.对于非模板函数和同名函数模板,如果条件相同,在调用的时候会优先调用非模板函数而不是从该模板实例化一个函数。如果模板可以产生一个更好匹配的函数则选择模板

#include <iostream>
using namespace std;
//专门的函数
void swap(int& a, int& b)
{int temp = a;a = b;b = temp;
}
//函数模板
template<typename T>
void swap(const T& a,const T& b)
{T temp = a;a = b;b = temp;
}
int main()
{int i = 1, j = 2;double d1 = 3.14, d2 = 2.71;char c1 = 'a', c2 = 'b';swap(i,j);//与非模板函数匹配,编译器无需优化swap(d1,d2);swap(c1,c2);cout << "i=" << i << " j=" << j << endl;cout << "d1=" << d1 << " d2=" << d2 << endl;cout << "c1=" << c1 << " c2=" << c2 << endl;swap(i,d1);//调用编译器优化的模板函数更匹配,根据实参生成更匹配的函数return 0;
}

        3.模板函数不允许自动类型转换,但是普通函数可以进行自动类型转换

类模板

        类模板定义格式

        

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

        模板不建议声明与定义分离,容易出问题。

#include<iostream>
using namespace std;
namespace MyNamespace
{template<typename T>class stack {public:stack(int n = 4):_a(new T[n]), _size(0), _capacity(n){}void print() {cout << "MyClass data: " << data << endl;}~stack(){delete[] _a;_a = nullptr;_size = 0;_capacity = 0;}private:T* a;size_t _size;size_t _capacity;};
}
int main()
{//类模板只能显式实例化MyNamespace::stack<int> s(10);MyNamespace::stack<double> d(3.14);return 0;
}

类模板实例化

        类模板实例化与函数模板实例化不同。类模板实例化需要类模板名字后面加<>,然后将实例化的类型放在<>中即可,类模板名字不是真的类,而实例化的结果才是真的类。

//stack是类名,stack<int>才是类型
stack<int>st1;    //int
stack<double>st2  //double

在之前写stack的时候,我们会用typedef来解决的

#include<iostream>
using namespace std;
namespace MyNamespace
{typedef int STDataType;class stack {public:stack(int n = 4):_a(new STDataType[n]), _size(0), _capacity(n){}void print() {cout << "MyClass data: " << data << endl;}~stack(){delete[] _a;_a = nullptr;_size = 0;_capacity = 0;}private:STDataType* a;size_t _size;size_t _capacity;};
}

        但是typedef的原理与类模板完全不一样(后者更复杂)。typedef相当于宏定义,在预处理阶段直接替换 ,但是我们用typedef的时候没办法实例化两个类型不一样的类,因此我们需要实例化两类型的类的时候需要用类的模板

        本期博客就先到这里了,模板的内容我们后续会更加深入的学习。各位读者大大求一个点赞,谢谢

http://www.dtcms.com/a/435602.html

相关文章:

  • ICT 数字测试原理 5 - -VCL 简介
  • 哪个网站域名便宜dedecms 购物网站
  • 网站首页包含的内容怎么做5080电影电视剧大全
  • Product Hunt 每日热榜 | 2025-10-01
  • 一块钱购物网站帝国cms7.0网站地图
  • 爬虫 API 开发:从架构设计到电商风控突破的全维度实践
  • 动态手机网站怎么做的网络行业做什么挣钱
  • LeetCode 148.排序链表
  • 做美食网站的特点怎么添加网站权重
  • 服装软件管理系统是什么?主要有哪几种类型?
  • ⚡ WSL2 搭建 s5p6818 Linux 嵌入式开发平台(Part 2):系统构建与系统部署
  • 网站别人备案怎么办赚钱网
  • wordpress网站接入qqwordpress怎么修改导航栏
  • 中山网站建设文化机构电商网站怎么做的
  • 福州市 2025 国庆集训 Day2 前三题题解
  • Java中的优先队列PriorityQueue
  • 宁波网站关键词做网站赚钱还是做应用赚钱
  • 重庆网站推广营销h5页面制作工具 软件
  • AI让产品越来越用户中心化
  • 襄阳做淘宝网站推广建设银行个人登录网站
  • 网站建设思维1级a做爰免费网站
  • 网站设计报告总结淘客免费网站建设
  • 又一个 wordpress 站点php网站建设填空题
  • 那个网站做图片好看wordpress 导入数据库结构
  • Bean后处理器
  • 一款可视化的自动复盘系统分享
  • 郑州正云网站建设慈溪网站建设慈溪
  • 我爱学算法之—— 分治-快排
  • asp网站后台上传不了图片wordpress无法加载图片
  • 什么软件 做短视频网站长尾关键词有哪些