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

海搜网做的网站怎么样各种手艺培训班

海搜网做的网站怎么样,各种手艺培训班,wordpress 登录接口,我要建网站今天我们来学习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/wzjs/517108.html

相关文章:

  • 东莞疫情情况 最新消息衡阳seo优化
  • wordpress怎么开放注册seo到底是什么
  • 网页的网站导航怎么做荆州seo推广
  • 本机网站建设河南品牌网站建设
  • 海拉尔做网站多少钱太原竞价托管公司推荐
  • 我要用新浪云做网站谷歌seo服务
  • 移动网站怎么做服务器租用
  • 网站开发有几种语言搜索引擎营销方案例子
  • 网站建设比较好郑州网站建设价格
  • 网站建设开发背景抚顺优化seo
  • 域名停靠性seo首页排名优化
  • 阿里巴巴国际站客服电话武汉seo招聘网
  • 域名网站怎么打开营销策划公司的经营范围
  • 做招聘网站需要什么人员营销型网站和普通网站
  • 10类地方网站 总有适合你做的楚雄今日头条新闻
  • 济南营销型网站建设seo外链专员
  • 手机网站建设的价格网店代运营靠谱吗
  • 在线做图的网站沈阳网络关键词排名
  • 建设部信息中心网站百度引擎搜索
  • 甘肃商城网站建设行者seo
  • 哪个网站可以做平面兼职软文广告发布平台
  • 做教育培训网站需要资质么游戏推广员是做什么的
  • 男生跟男生做口视频网站seo外包公司兴田德润官方地址
  • 如何优化网站速度微商软文大全
  • 网站左侧浮动代码优化教程
  • 凡科网站为什么免费做网站北京网站托管
  • 万达做的电商网站百度推广价格价目表
  • 建设个人网站用到的技术口碑营销案例分析
  • 刷单平台网站建设深圳谷歌网络推广公司
  • 做app和网站怎样最近国际新闻大事20条