C++C7-模板

本文深入探讨了C++中的模板机制,包括函数模板和类模板。介绍了函数模板的声明、实现原理以及如何通过模板参数创建重载函数。同时,详细阐述了类模板的声明、成员函数的定义以及类模板的实例化。文章还讨论了模板与普通函数的重载选择,并给出了类模板派生的示例。关键词涵盖模板、函数模板、类模板、模板参数、重载、类模板派生。
摘要由CSDN通过智能技术生成

模板的概念

	所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表。这个通用函数就称为函数模板。
	C++提供两种模板机制:函数模板、类模板

函数模板

	template<模板参数列表>
	<函数返回类型> 函数名(<函数参数列表>)
	1、template模板声明
	2、<模板参数>可以有一个,也可以有多个,逗号隔开
	3、<函数返回类型> 一种就是模板参数
								 一种就是普通函数
	4、<函数参数列表>可以是模板参数,也可以是普通类型

实现原理:“两次编译”
(声明)函数模板不是以恶真正的函数,编译系统不给他产生任何可执行代码
(函数模板只是对函数的描述)
(编译)当编译系统发现函数调用的时候,表一系统会更具实参的类型,先匹配,如果匹配成功,会生成一个重载函数。
该重载函数的定义体与函数模板的定义体相同,
只不过是用实参的实际类型去替换函数形参表中与模板参数表相同的数据类型
该重载函数成为模板函数

#include <iostream>
using namespace std;

template <class T> void swap(T *a,T *b)
{
	T temp = *a;
	*a = *b;
	*b = temp;
}


template <class T> T myadd(T a,T b)
{
	T temp;
	temp = a+b;
	return temp;
}
int main()
{
	int i = 10;
	int j = 20;
	swap(i,j);     //void swap(int a,int b)
	cout << myadd(i,j) << endl;
	cout << i << "," << j << endl;

	double a = 11.34;
	double b = 23.78;
	swap(a,b);    //void swap(double a,double b)
	cout << myadd(a,b) << endl;
	cout << a << "," << b << endl;

	system("pause");
	return 0;
}

模板参数是自定义类型时

注意要有运算符重载

#include <iostream>
using namespace std;

class CPoint
{
private:
	int x;
	int y;
public:
	CPoint(int x,int y)
	{
		this->x = x;
		this->y = y;
	}
	CPoint()
	{
		x = 0;
		y = 0;
	}
	CPoint operator+(CPoint c);
	friend ostream& operator<<(ostream& os,CPoint c);
};

CPoint CPoint::operator+(CPoint c)
{
	CPoint temp(0,0);
	temp.x = this->x + c.x;
	temp.y = this->y + c.y;
	return temp;
}
ostream& operator<<(ostream& os,CPoint c)
{
	os << "(" << c.x << "," << c.y << ")." << endl;
	return os;
}

//template <class T> void myswap(T *a,T *b)
//{
//	T temp = *a;
//	*a = *b;
//	*b = temp;
//}
template <class T> void myswap(T &a,T &b)
{
	T temp = a;
	a = b;
	b = temp;
}


template <class T> T myadd(T a,T b)
{
	T temp;
	temp = a+b;
	return temp;
}
int main()
{
	int i = 10;
	int j = 20;
	myswap(i,j);
	cout << myadd(i,j) << endl;
	cout << i << "," << j << endl;

	double a = 11.34;
	double b = 23.78;
	myswap(a,b);
	cout << myadd(a,b) << endl;
	cout << a << "," << b << endl;


	CPoint c1(1,2);
	CPoint c2(4,5);
	cout << myadd(c1,c2) << endl;

	system("pause");
	return 0;
}

当函数模板遇上重载函数

/*
宏定义
 #define myMax(x,y) ((x>y)?a:b)
宏定义与函数模板的区别:
	宏定义只是简单的文本替换,不做类型检查(万一两个参数类型都不一样)


函数模板遇上重载函数
 *如果有一个非模板函数的参数与函数调用的参数一致,那么调用这个非模板函数
 (int myMax(int a,int b))  (优先考虑普通函数调用)
 *如果从相应模板生成的模板函数中,有一个模板函数的参数与之相匹配,那就...
 *从相对应参数类型转换之后匹配非模板函数
 (模板函数没有隐式类型转换,普通函数有)

*/

#include <iostream>
#include <cstring>

#define d_Max(x,y) ((x>y)?x:y)
using namespace std;

class CPoint
{
private:
	int x;
	int y;
public:
	CPoint(int x,int y)
	{
		this->x = x;
		this->y = y;
	}
	CPoint()
	{
		x = 0;
		y = 0;
	}
	friend int operator>(CPoint &c1,CPoint &c2);
	friend ostream& operator<<(ostream& os,CPoint &c);

};

int operator>(CPoint &c1,CPoint &c2)
{
	int distance = (c1.x*c1.x+c1.y*c1.y)-(c2.x*c2.x+c2.y*c2.y);
	return distance>0?1:0;
}

ostream& operator << (ostream& os,CPoint &c)
{
	os << "(" << c.x << "," << c.y << ")." << endl;
	return os;
}


template <class T>
T myMax(T a,T b)
{
	cout << "tem" << endl;
	return a>b?a:b;
}

int myMax(int a,int b)
{
	cout << "普通函数" << endl;
	return a>b?a:b;
}

char* myMax(char* a,char *b)
{
	return strcmp(a,b)>0?a:b;
}

int main()
{
	cout << myMax(1,3) << endl;
	cout << myMax('A','D') << endl;

	//cout << myMax(1,'A') << endl;
	cout << d_Max(1,'A') << endl; //宏定义只是简单的文本替换,不做类型检查


	CPoint c1(3,4);
	CPoint c2(5,12);
	cout << myMax(c1,c2) << endl;

	return 0;
}

类模板

类模板:(比较适用于各种数据结构)

语法:
声明:
template class <类模板名>
{

}
	class_1 :模板参数声明
	class_2 :类的声明

类外写成员函数:
	template <class T>
	<返回值类型> 类模板名(<模板参数表>)::成员函数(<形参表>)

创建实例:
类名<模板数据类型表> 对象名(<…>);
A a(100);

stack类(类模板)

#include <iostream>
using namespace std;

template <class T>
class mystack   //类型:  mystack<T>
{
private:
	int size;    //数组大小
	int top;     //栈顶指针(不是真的指针,只是用来表明栈顶元素位置)
	T *stackptr; //指向堆栈存储空间的指针(数组名)
public:
	mystack(int s);
	~mystack(){delete[] stackptr;}
	bool push(T pushvalue);
	bool pop();
	bool isEmpty(){return top == -1;}
	bool isFull(){return top == size-1;}
	int get_top(){return top;}
};

template <class T>
mystack<T>::mystack(int s)
{
	size = s>0?s:10;
	top = -1;
	stackptr = new T[size];
}

template <class T>
bool mystack<T>::push(T pushvalue)
{
	if(!isFull())
	{
		stackptr[++top] = pushvalue;
		return true;
	}
	return false;
}

template <class T>
bool mystack<T>::pop()
{
	if(!isEmpty())
	{
		stackptr[top--];
		return true;
	}
	return false;
}


int main()
{
	mystack<double> doublestack(5);
	double f=0.1;
	while(doublestack.push(f))
	{
		cout << f << " ";
		f++;
	}
	cout << endl;
	cout << doublestack.isFull() << endl;
	while(doublestack.pop())
	{
		cout << doublestack.get_top() << endl;
	}
	cout << endl;
	cout << doublestack.isEmpty() << endl;

	system("pause");
	return 0;
}

普通类派生出类模板

#include <iostream>
using namespace std;

class Base
{
private:
	int a;
protected:
	int b;
public:
	void fun()
	{
		cout << "base fun" << endl;
	}
};

template <class T>
class Derived:public Base   //普通类派生出类模板
{
protected:
	T t;
public:
	void fun()
	{
		//b = 10;
		cout <<  "derived fun" << endl;
	}
};

int main()
{
	Derived<int> dint;
	dint.fun();

	system("pause");
	return 0;
}

类模板派生出类模板

#include <iostream>
using namespace std;

template <class T>
class Base
{
protected:
	T t;
public:
	Base(T t)
	{
		this->t = t;
	}
	void fun()
	{
		cout << "t:" << t << endl; 
	}
};

template <class T1,class T2>
//class T1表示派生类自身的模板参数
//class T2表示基类中模板参数
class Derived:public Base<T2>
{
private:
	T1 x;
	T2 y;
public:
	Derived(T1 x,T2 y,T2 t):Base(t)
	{
		this->x = x;
		this->y = y;
	}
	void fun()
	{
		cout << "t:" << t << endl; 
		cout << "x:" << x << endl; 
		cout << "y:" << y << endl; 
	}
};

int main()
{
	Derived<double,int> d1(10.07,20,30);
	d1.fun();

	system("pause");
	return 0;
}

类模板中static关键字

类模板根据类型产生不同的模板类
Test
Tets , Test
在不同的模板类的对象中共享这个static成员变量

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值