C++模板函数示例
Posted Roam-G
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++模板函数示例相关的知识,希望对你有一定的参考价值。
9.1//求绝对值函数的模板
编译器从调用abs()时实参的类型,推导出函数模板的类型参数。例如,对于调用表达式abs(n),由于实参n为int型,所以推导出模板中类型参数T为int。
当类型参数的含义确定后,编译器将以函数模板为样板,生成一个函数:int abs(int x) { return x < 0 ? –x : x;}
//求绝对值函数的模板
#include <iostream>
using namespace std;
template<typename T>
T abs(T x) {
return x < 0 ? -x : x;
}
int main() {
int n = -5;
double d = -5.5;
cout << abs(n) << endl;
cout << abs(d) << endl;
return 0;
}
例9-1模板函数示例
#include <iostream>
using namespace std;
template<class T> //定义类模板
void outputArray(const T* array, int count) {
for (int i = 0;i < count;i++) {
cout << array[i] << " ";
}
cout << endl;
}
int main() {
const int A_COUNT = 8, B_COUNT = 8, C_COUNT = 20;
//定义int数组
int a[A_COUNT] = { 1,2,3,4,5,6,7,8 };
//定义double数组
double b[B_COUNT] = { 1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8 };
//定义char数组
char c[C_COUNT] = "Welcome to see you!";
cout << "a array contains:" << endl;
//调用类模板
outputArray(a, A_COUNT);
cout << "b array contains:" << endl;
//调用类模板
outputArray(b, B_COUNT);
cout << "c array contains:" << endl;
//调用类模板
outputArray(c, C_COUNT);
return 0;
}
类模板的作用
使用类模板使用户可以为类声明一种模式,使得类中的某些数据成员、某些成员函数的参数、某些成员函数的返回值,能取任意类型(包括基本类型的和用户自定义类型)。
类模板:
template <模板参数表>
class 类名
{类成员声明}
如果需要在类模板以外定义其成员函数,则要采用以下的形式:
template <模板参数表>
类型名 类名<模板参数标识符列表>::函数名(参数表)
例9-2
//9-2.cpp类模板示例
#include <iostream>
#include <cstdlib>
using namespace std;
//学生结构体
struct Student
{
int id; //学号
float gpa; //学分
};
template<class T>
//类模板 实现对任意 类型的数据进行存取。
class Store {
private:
T item; //存放任意类型的数据
bool haveValue; //标记item是否已经被存入数据
public:
//无参构造
Store();
T& getElem(); //提取数据函数
void putElem(const T& x); //存入数据函数
};
//默认构造函数的实现
template<class T>
Store<T>::Store():haveValue(false){}
//提取函数的实现
template<class T>
T& Store<T>::getElem() {
//如果试图提取未初始化的数据,则终止程序
if (!haveValue) {
cout << "No item present!" << endl;
//使程序完全退出,返回到操作系统
exit(1);
}
//返回item中的数据
return item;
}
//存入数据函数的实现
template<class T>
void Store<T>::putElem(const T& x) {
//将haveValue设置为 true ,表示 已经存入数据
haveValue = true;
item = x;//将x存入item
}
int main() {
Store<int> s1, s2;
s1.putElem(3);
s2.putElem(-7);
cout << s1.getElem() << " " << s2.getElem() << endl;
Student g = { 1000,23 };
Store<Student> s3;
s3.putElem(g);
cout << "The student id is " << s3.getElem().id << endl;
Store<double> d;
cout << "Retrieving object D..."<<endl;
cout <<d.getElem()<<endl;
//由于 d 未 经过 初始化,会导致程序终止
return 0;
}
例9-3 动态数组类模板程序
#ifndef ARRAY_H
#define ARRAY_H
#include <cassert>
//数组类模板定义
template<class T>
class Array {
private:
T* list; //存放动态分配的数组内存首地址
int size; //数组元素个数
public:
Array(int sz = 50); //构造函数
Array(const Array<T>& a); //复制构造函数
~Array(); //析构函数
//重载 =
Array<T>& operator = (const Array<T>& rhs);
//重载 []
T& operator [](int i);
const T& operator [](int i)const;
//重载 到T*类型的转换
operator T* ();
operator const T* ()const;
int getSize() const; //取数组的大小
void resize(int sz); //修改数组的大小
};
//构造函数
template <class T> Array<T>::Array(int sz) {
assert(sz >= 0); //sz 必须非负
size = sz;
list = new T[size]; //动态分配size个T类型的元素空间
}
//析构函数
template <class T> Array<T>::~Array() {
delete[]list;//释放数组
}
//复制构造函数
template <class T> Array<T>::Array(const Array<T>& a) {
//从 对象x取得数组的大小,并赋值为当前的对象成员
size = a.size;
//为对象 申请 内存并进行出错检查
list = new T[size];
//从对象 x 复制数组元素到本对象
for (int i = 0;i < size;i++) {
list[i] = a.list[i];
}
}
//重载 = 运算符 将 对象 rhs 赋值为本对象,实现对象之间的整体赋值
template<class T>
Array<T>& Array<T>::operator = (const Array<T>& rhs) {
if (&rhs != this) {
//如果 本对象中数组大小和rhs不同,则删除数组原有内存,并重新分配
if (size != rhs.size){
delete[]list;
size = rhs.size;
list = new T[size];
}
//从对象x复制数组元素到本对象
for (int i = 0;i < size;i++) {
list[i] = rhs.list[i];
}
}
//返回当前对象的引用
return *this;
}
//重载下标运算符,实现和普通数组一样通过下标访问元素,并且具有越界检查功能
template<class T>
T& Array<T>::operatorp[](int n) {
//检查下标是否越界
assert(n >= 0 && n < size);
//返回下标为n 的数组元素
return list[n];
}
template<class T>
const T& Array<T>::operator[] (int n)const {
assert(n >= 0 && n < size);
return list[n];
}
//重载指针转换运算符,将array类的对象名 转换为 T 类型的指针
template<class T>
Array<T>::operator T* () {
return list;//返回当前 对象中私有数组的首地址
}
template<class T>
Array<T>::operator const T* ()const {
return list;
}
//取当前数组的大小
template<class T>
int Array<T>::getSize()const {
return size;
}
//将数组大小修改为sz
template<class T>
void Array<T>::resize(int sz) {
//检查sz是否非负
assert(sz >= 0);
//如果指定的大小 和原有的大小一样,
//什么也不用做
if (sz == size) {
return;
}
//申请新的 数组内存
T* newList = new T[sz];
//将sz和size比较中娇小的一个赋值给n
int n = (sz < size) < sz:size;
//将 原有数组中前n个元素复制到新数组中
for (int i = 0;i < n;i++) {
newList[i] = list[i];
}
//删除原有数组
delete[] list;
//使list 指向新的数组
list = newList;
//更行size
size = sz;
}
#endif //ARRAY_H
C++ 常量
常量可以是任何的基本数据类型,可分为整型数字、浮点数字、字符、字符串和布尔值
整数常量可以是十进制、八进制或十六进制的常量。
前缀指定基数:0x 或 0X 表示十六进制,0 表示八进制,不带前缀则默认表示十进制。
整数常量也可以带一个后缀,后缀是 U 和 L 的组合,U 表示无符号整数(unsigned),L 表示长整数(long)。后缀可以是大写,也可以是小写,U 和 L 的顺序任意
浮点常量由整数部分、小数点、小数部分和指数部分组成。您可以使用小数形式或者指数形式来表示浮点常量。
当使用小数形式表示时,必须包含整数部分、小数部分,或同时包含两者。当使用指数形式表示时, 必须包含小数点、指数,或同时包含两者。带符号的指数是用 e 或 E 引入的。
C++强制类型转换操作符 static_cast
static_cast是一个强制类型转换操作符。强制类型转换,也称为显式转换,C++中强制类型转换操作符有static_cast、dynamic_cast、const_cast、reinterpert_cast四个。本节介绍static_cast操作符。
C++强制类型转换操作符 static_cast - melonstreet - 博客园
cout<<" Score"<<static_cast<float>(numCorrect)/NUM_QUES*100<<"%";
cout<<" Score"<<numCorrect/NUM_QUES*100<<"%";
以上是关于C++模板函数示例的主要内容,如果未能解决你的问题,请参考以下文章
调用模板化成员函数:帮助我理解另一个 *** 帖子中的代码片段
我的Android进阶之旅NDK开发之在C++代码中使用Android Log打印日志,打印出C++的函数耗时以及代码片段耗时详情