C++学习8-面向对象编程基础(模板)
模板
模板是一种工具,模板可以使程序员能建立具有通用类型的函数库与类库;
模板具有两种不同的形式;
- 函数模板
- 类模板
函数模板
当一个add()函数接收两个参数,因为某种特定情况,所传入的实参数据类型不同,两个函数主体内行为处理是一样的;一个是处理int型的,另一个是处理double型的,
这种情况时,可以写出不同的形参的同名函数,构成函数重载。但这样的零散函数并不是很优雅,开发时还增加编程量;
出现这种情况时,使用函数模板来解决,即可以实现对于任何一个类型T的两个对象a,b的功能,也可以使函数调用add(a,b)合法,让编译器理解为两个相同类型的实体交换;
模板使用格式:函数模板提供了具有处理相同功能的一类函数的抽象,它以任意类型T为参数,其定义形式如下:
template <typename 参数化类型名>
<返回类型> <函数名> (<参数表>)
{
//<函数体>
}
例如:
template <typename T>
T add(T a,T b)
{
//....
}
实例代码
以下代码分别以成员函数重载,与函数模板使用;
#include "stdafx.h"
//两个同名函数,传入参数的数据类型不同时,写两个函数构成重载函数才能使用。
//其中一个add()函数传入两个int型;
//double Add(int a,int b)
// {
// return a + b;
// }
//
////其中一个add()函数传入两个double型
// double Add(double a , double b)
// {
// return a + b;
// }
//写成模板形式两个相同类型的实参数值,匹配到第一个模板函数
//因为减少了重载的编码量,使用模板后代码量减少,且程序变得更加优雅~~
template <typename T>
T Add(T a, T b)
{
return a + b;
}
int _tmain(int argc, _TCHAR* argv[])
{
//下面的函数传入两个int型的数值
double na = Add(10.2, 20.5);
//下面两个参数都是double型的数值
double fa = Add(10, 20);
return 0;
}
重载函数模板
函数模板也可以像函数重载一样使用,例如传入的实参如果是两个不同类型如float、int,或者是函数定义的形参个数不一致的时候会自定调用与传入实参个数类型相匹配的函数;
函数模板匹配的优先次序
在使用函数模板后,调用函数还是会有优先顺序的。
1.完全匹配
当匹配普通函数的形参时,则优先调用普通函数;
2.匹配函数模板
如果不匹配普通函数,则视其数据实参的类型来选择重载函数模板中的一个。
3.类型自动转换后匹配
在测试过程中,类型转换顺序取由左到右的第一个参数类型进行数据类型转换,产生参数匹配的函数;
实例代码
#include "stdafx.h"
//两个同名函数,传入参数的数据类型不同时,写两个函数构成重载函数才能使用。
//其中一个传入两个int型;
//double Add(int a,int b)
// {
// return a + b;
// }
//
////其中一个传入两个double型
// double Add(double a , double b)
// {
// return a + b;
// }
////两个相同类型的实参数值,匹配到第一个模板函数
//因为减少了重载的编码量,使用模板后代码量减少,且程序变得更加优雅~~
template <typename T>
T Add(T a, T b)
{
return a + b;
}
//重载函数模板
template <typename T>
T Add(T a)
{
return a;
}
//不同的类型可以定义两个模板类型
template <typename T1, typename T2>
T2 my_add(T1 NumA, T2 NumB)
{
return NumA + NumB;
}
int _tmain(int argc, _TCHAR* argv[])
{
//下面Add()函数有两个参数;
double na = Add(10.2, 20.5);
//下面Add()函数只有一个参数;
double fa = Add(10);
//下面的函数调用两个参数自动匹配模板类型
cout << my_add(1, 3.4) << endl;
cout << my_add(1.2, 'A') << endl;
cout << my_add(2, 'A') << endl;
return 0;
}
模板特化
#include "stdafx.h"
#include <stdlib.h>
#include <iostream>
using std::cout; using std::endl;
template <typename T>
T MyMax(const T NumA, const T NumB) {
return NumA < NumB ? NumB : NumA;
}
template <>
const char* MyMax<const char*>(const char* pStrA, const char* pStrB) {
return (strcmp(pStrA, pStrB) < 0) ? pStrB : pStrA;
}
int _tmain(int argc, _TCHAR* argv[]) {
cout << MyMax("AAAA", "BBBB") << endl;
system("pause");
return 0;
}
类模板
如果要对功能相同、类的实现没有变化,仅类的数据类型不同的各种情况,都要重新定义一种新的类型,将带来较大的重复。为解决这一问题, 可以引进类模板的概念。就是将数组中的元素和链表中的结点的数据类型用一个通用参数T来代替;
类模板的定义格式为:
template <typename T>
class <类名>
{
//类体说明
}
其中template是关键字,<模板参数表>中可以有多个参数,其间用逗号分隔。
注:当定义成类模板后,那么成员函数与类应该在同一个文件内。无法分开存放声明与定义;
实例代码
#include "stdafx.h"
#include <stdlib.h>
#include <iostream>
using std::cout; using std::endl;
//声明模板类,类型为T
template <class T>
class CVector {
public:
CVector(int nCount) : m_nSize(nCount) {
//表示开辟的空间为模板T类型
m_pData = new T[nCount];
memset(m_pData, 0, nCount);
}
~CVector() { delete m_pData; }
//重载下标符号,定义重载为T类型
T operator[](int nIndex)
{
return m_pData[nIndex];
}
//如果不用模板的情况应该是char类型
//char operator[](int nIndex)
//{
// return m_pData[nIndex];
//}
int fun();
private:
//定义m_pData为模板类型T
T *m_pData;
int m_nSize;
};
//类体外实现成员函数的语法(不能放在cpp中,只能一起放在.h文件中)
template <class T>
int CVector<T>::fun()
{
}
int _tmain(int argc, _TCHAR* argv[]) {
//这个时候,T就是int型
CVector<int> objNum(15);
cout << objNum[1] << endl;
system("pause");
return 0;
}
C++学习8-面向对象编程基础(模板)的更多相关文章
- 大数据技术之_16_Scala学习_04_函数式编程-基础+面向对象编程-基础
第五章 函数式编程-基础5.1 函数式编程内容说明5.1.1 函数式编程内容5.1.2 函数式编程授课顺序5.2 函数式编程介绍5.2.1 几个概念的说明5.2.2 方法.函数.函数式编程和面向对象编 ...
- Python学习-第三天-面向对象编程基础
Python学习-第三天-面向对象编程基础 类和对象 简单的说,类是对象的蓝图和模板,而对象是类的实例.这个解释虽然有点像用概念在解释概念,但是从这句话我们至少可以看出,类是抽象的概念,而对象是具体的 ...
- JAVA学习(五):Java面向对象编程基础
Java面向对象编程基础 面向对象(Object oriented programming,OOP)技术是一种强有力的软件开发方法,它採用数据抽象与信息隐藏技术,来使软件开发简单化,以达到代码重用的目 ...
- [.net 面向对象编程基础] (15) 抽象类
[.net 面向对象编程基础] (15) 抽象类 前面我们已经使用到了虚方法(使用 Virtual修饰符)和抽象类及抽象方法(使用abstract修饰符)我们在多态一节中说到要实现类成员的重写必须定义 ...
- [.net 面向对象编程基础] (16) 接口
[.net 面向对象编程基础] (16) 接口 关于“接口”一词,跟我们平常看到的电脑的硬件“接口”意义上是差不多的.拿一台电脑来说,我们从外面,可以看到他的USB接口,COM接口等,那么这些接口的目 ...
- 第二章 Matlab面向对象编程基础
DeepLab是一款基于Matlab面向对象编程的深度学习工具箱,所以了解Matlab面向对象编程的特点是必要的.笔者在做Matlab面向对象编程的时候发现无论是互联网上还是书店里卖的各式Matlab ...
- [.net 面向对象编程基础] (1) 开篇
[.net 面向对象编程基础] (1)开篇 使用.net进行面向对象编程也有好长一段时间了,整天都忙于赶项目,完成项目任务之中.最近偶有闲暇,看了项目组中的同学写的代码,感慨颇深.感觉除了定义个类,就 ...
- [.net 面向对象编程基础] (7) 基础中的基础——流程控制语句
[.net 面向对象编程基础] (7) 基础中的基础——流程控制语句 本来没有这一节的内容,后来考虑到既然是一个系列文章,那么就尽可能写的详细一些,本节参考了网上朋友所写的例子,为的是让更多小伙伴学习 ...
- [.net 面向对象编程基础] (14) 重构
[.net 面向对象编程基础] (14) 重构 通过面向对象三大特性:封装.继承.多态的学习,可以说我们已经掌握了面向对象的核心.接下来的学习就是如何让我们的代码更优雅.更高效.更易读.更易维护.当然 ...
- [.net 面向对象编程基础] (17) 数组与集合
[.net 面向对象编程基础] (17) 数组与集合 学习了前面的C#三大特性,及接口,抽象类这些相对抽象的东西以后,是不是有点很累的感觉.具体的东西总是容易理解,因此我们在介绍前面抽象概念的时候,总 ...
随机推荐
- MT【230】一道代数不等式
设$a,b,c>0,$满足$a+b+c\le abc$证明:$\dfrac{1}{\sqrt{1+a^2}}+\dfrac{1}{\sqrt{1+b^2}}+\dfrac{1}{\sqrt{1+ ...
- 自学Zabbix6.1 Event acknowledgment 事件确认
自学Zabbix6.1 Event acknowledgment 事件确认 1 概述以往服务器出现报警,运维人员处理完事之后,报警自动取消,但是下一次出现同样一个错误,但是换了一个运维人员,他可能需要 ...
- 洛谷 P1627 [CQOI2009]中位数 解题报告
P1627 [CQOI2009]中位数 题目描述 给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b.中位数是指把所有元素从小到大排列后,位于中间的数. 输入输出格式 输入格式 ...
- [转载]Best Practices for Speeding Up Your Web Site
原文:http://developer.yahoo.com/performance/rules.html 提升网站加载速度的一些优化技巧,大部分在前端层面. 不知道是多久以前写的,看起来有些已经过时了 ...
- luogu3810 陌上花开 (cdq分治)
求三维偏序 设三维为a,b,c.先对a排序,这样i的偏序就只能<i. 然而排序的时候需要三个维度都判断一遍,最后还要去重,不然会出现实际应该记答案的数出现在它后面的情况. (排序用的函数里不要写 ...
- (string 高精度) Lovekey hdu 2100
Lovekey Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Su ...
- sizeof 与 字节对齐
转:http://baike.baidu.com/view/1356720.htm sizeof是运算符,可用于任何变量名.类型名或常量值,当用于变量名(不是数组名)或常量时,它不需要用圆括号. ...
- python爬虫-采集英语翻译
http://fanyi.baidu.com/?aldtype=85#en/zh/drughttp://fanyi.baidu.com/?aldtype=85#en/zh/cathttp://fa ...
- Hadoop集群-HDFS集群中大数据运维常用的命令总结
Hadoop集群-HDFS集群中大数据运维常用的命令总结 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客会简单涉及到滚动编辑,融合镜像文件,目录的空间配额等运维操作简介.话 ...
- xen 基础命令学习
# 查看创建的虚拟机的uuid xe vm-list # 开启虚拟机启动顺序功能 xe vm-param-set HVM-boot-policy="BIOS order" uuid ...