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

西安企业网站设计公司网页广告怎么投放

西安企业网站设计公司,网页广告怎么投放,wordpress能做商城吗,seo网站制作C模板入门 一、泛型编程 二、函数模板1. 函数模板的概念2. 函数模板格式3. 函数模板的原理4. 函数模板的实例化5. 模板参数的匹配原则 三、类模板 一、泛型编程 假设我们想实现一个交换函数,并且支持不同类型的参数实现,我们可以用 typedef 将类型进行重…

C++模板入门

    • 一、泛型编程
  • 二、函数模板
    • 1. 函数模板的概念
    • 2. 函数模板格式
    • 3. 函数模板的原理
    • 4. 函数模板的实例化
    • 5. 模板参数的匹配原则
  • 三、类模板

一、泛型编程

假设我们想实现一个交换函数,并且支持不同类型的参数实现,我们可以用 typedef 将类型进行重命名,例如以下代码:

		// 将 int 起别名为 DataTypetypedef int DataType;void Swap(DataType& x, DataType& y){DataType tmp = x;x = y;y = tmp;}int main(){DataType x = 0, y = 6;Swap(x, y);return 0;}

这样我们每次需要更换类型的时候,只需要更改 int 为其他类型即可;

以上是一种方法,还有一种方法可以使用函数重载实现,例如:

		void Swap(int& left, int& right){int temp = left;left = right;right = temp;}void Swap(double& left, double& right){double temp = left;left = right;right = temp;}void Swap(char& left, char& right){char temp = left;left = right;right = temp;}

以上两种方法虽然可以实现通用的交换函数,但是有以下几个不好的地方:

  1. 重载的函数仅仅是类型不同,代码复用率比较低,只要有新类型出现时,就需要用户自己增加对应的函数或修改类型。
  2. 代码的可维护性比较低,一个出错可能所有的重载均出错。

那能否告诉编译器一个模板,让编译器根据不同的类型利用该模板来生成代码呢?答案是可以的,在这里就需要引入泛型编程,泛型编程: 编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。

模板分为函数模板类模板

二、函数模板

1. 函数模板的概念

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

2. 函数模板格式

在定义函数模板之前,我们需要引入一个关键字:template,它是定义模板的关键字;

使用格式:template<typename T1, typename T2,......,typename Tn>,在 template 关键字后面要用尖括号括住模板参数,模板参数的数量可以是任意的,但是需要使用 typename 关键字来定义模板参数,也可以使用 class(切记:不能使用struct代替class)。

例如交换函数的函数模板:

		template<typename T>void Swap(T& t1, T& t2){T tmp = t1;t1 = t2;t2 = tmp;}

3. 函数模板的原理

函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。所以其实模板就是将本来应该我们做的重复的事情交给了编译器。

例如下图就很好地体现了这一个过程:

在这里插入图片描述

在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供调用。

比如:当用 double 类型使用函数模板时,编译器通过对实参类型的推演,将 T 确定为 double 类型,然后产生一份专门处理 double 类型的代码,对于字符类型也是如此,即编译器用模板实例化生成对应的Swap 函数。

4. 函数模板的实例化

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

隐式实例化: 让编译器根据实参推演模板参数的实际类型,例如以下这个 Add 的函数模板,实现两个数的相加:

		template<class T>T Add(T a, T b){return a + b;}int main(){int a = 10, b = 20;double c = 1.11, d = 2.22;cout << "sum = " << Add(a, b) << endl;cout << "sum = " << Add(c, d) << endl;return 0;}

上面的两个调用实例化都没有问题,编译器进行了隐式实例化,运行的结果如下:

在这里插入图片描述

但是如果这样调用会编译通过吗:Add(a, d),答案是不行的,通过实参 a 将 T 推演为 int,通过实参 dT 推演为 double 类型,但模板参数列表中只有一个 T, 编译器无法确定此处到底该将 T 确定为 int 或者 double 类型而报错。

所以此时有两种解决方法:

  1. 用户自己来强制转化
  2. 使用显式实例化

如果自己来强制转化,就可以使用以下方法:

		int main(){int a = 10, b = 20;double c = 1.11, d = 2.22;cout << "sum = " << Add((double)a, d) << endl;cout << "sum = " << Add(a, (int)d) << endl;return 0;}

我们可以在调用 Add 函数时,将 a 强转为 double,或者将 d 强转为 int

显式实例化: 在函数名后的<>中指定模板参数的实际类型。

例如上面的问题中,我们使用显式实例化解决,代码如下:

		int main(){int a = 10, b = 20;double c = 1.11, d = 2.22;cout << "sum = " << Add(a, b) << endl;cout << "sum = " << Add(c, d) << endl;cout << "sum = " << Add<double>(a, d) << endl;cout << "sum = " << Add<int>(a, d) << endl;return 0;}

我们在函数名的后面用尖括号指定了模板参数的类型,这就是显式实例化。

注意:如果类型不匹配,编译器会尝试进行隐式类型转换,如果无法转换成功编译器将会报错。

5. 模板参数的匹配原则

对于非模板函数同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数, 那么将选择模板。

例如以下两段代码:

		// 专门处理int的加法函数int Add(int a, int b){cout << "int Add(int a, int b)" << endl;return a + b;}// 通用加法函数template<class T>T Add(T a, T b){cout << "T Add(T a, T b)" << endl;return a + b;}int main(){// 与非函数模板类型完全匹配,不需要函数模板实例化Add(1, 2); // 模板函数可以生成更加匹配的版本,编译器根据实参生成更加匹配的 Add 函数Add<int>(1, 2); return 0;}

三、类模板

假设我们我们需要实现一个通用的栈,我们可以使用 typedef 关键字对类型起别名,每次需要改变类型的时候,只需要在 typedef 更改即可,例如以下的 Stack 类:

		typedef int DataType;class Stack{public:Stack(size_t capacity = 4){_array = new DataType[capacity];_capacity = capacity;_size = 0;}~Stack(){cout << "~Stack()" << endl;delete[] _array;_array = nullptr;_size = _capacity = 0;}private:// 内置类型DataType* _array;int _capacity;int _size;};

虽然以上的 Stack 类不同的类型只需要改变 typedef 的类型即可,但是如果我同时需要两个栈,一个栈的参数是 int ,另一个栈的参数是 double 呢,上面的方法就不能很好地满足了,所以我们引入类模板。

类模板的使用如下,以 Stack 类为例:

		template<class T>class Stack{public:Stack(size_t capacity = 4){_array = new T[capacity];_capacity = capacity;_size = 0;}~Stack(){delete[] _array;_array = nullptr;_size = _capacity = 0;}private:T* _array;int _capacity;int _size;};

实例化对象如下:

		int main(){Stack<int> st1;Stack<double> st2;return 0;}

注意,Stack 是类名,Stack<int>Stack<double> 才是类型;template 的作用范围是 Stack 这个类。

这样我们就同时实现了两个栈,一个栈存放的参数是 int,另外一个存放的是 double

http://www.dinnco.com/news/45851.html

相关文章:

  • 织梦开发小说网站教程国内最新新闻事件今天
  • 保健品做哪个网站好网络整合营销理论
  • 政务公开与网站建设网站注册账号
  • 重庆建设厂seo网络优化招聘信息
  • wordpress取消邮件验证码宁波网站推广优化公司怎么样
  • 创建网站的ip地址怎么获得seo如何优化图片
  • 公司网站建设备选方案评价标准seo网站推广全程实例
  • wordpress页脚东莞百度seo电话
  • 网站视频开发平台自动收录
  • 打开网站notfound百度手机助手网页
  • 东台网站建设找哪家好手机上怎么制作网页
  • 网站程序开发要点上海网站建设关键词排名
  • 个人网站怎么做微信支付怎么做网站免费的
  • 公司网站开发排名上海专业seo
  • 唐山网站建设电话广东网站seo策划
  • 货车保险哪家网站可以直接做电商运营培训课程
  • 网站想自己做怎么弄中国十大网络销售公司
  • 医疗网站前置审批查询搜索引擎优化seo公司
  • 电脑游戏网站平台大全网站提交收录入口
  • 威海网站建设公司杭州seo平台
  • 加强网站建设的制度广告招商
  • 男直接做的视频网站百度服务热线
  • 网站如何做3d产品展示学生网页设计模板
  • 昆明网络营销公司哪家好wp博客seo插件
  • 网站建设方案书手机百度正式版
  • 做精品课程网站需要啥素材最火的推广平台
  • 东莞大岭山网站建设安徽关键词seo
  • h5做网站重庆seo公司
  • php培训机构企业做网站沈阳网站制作公司
  • 淄博哪个网站做房屋出赁好查询友情链接