C++ 模板template

C++ 模板

  C++另一种编程思想称为泛型编程,主要利用的技术就是模板。

  C++提供了两种模板机制:函数模板类模板

函数模板

  作用:建立一个通用函数,其函数返回值类型可以不具体的制定,用一个虚拟的类型来代表。

语法:

template<typename T>
函数

  template------声明创建模板
  typename------表明后面的符号是一种数据类型,可以用class代替
  T------通用的数据类型,名称可以替换,通常为大写字母

两种方式使用模板函数:自动类型推导和显示指定类型
  自动类型推导:在使用模板时不需要写参数类型,可根据参数定义自动确定数据类型
  显示指定类型:在使用模板时需要在参数前面<>内写数据类型

例子:
//用模板实现两个数的交换,可以交换int 型和double型

#include<iostream>
#include<string>
using namespace std;

template<typename T>
void myswap(T &a,T &b)
{
	T temp = a;
	a = b;
	b = temp;
}
void fun1()
{
	int a = 6;
	int b = 9;
	double c = 1;
	double d = 2;
	myswap(a, b);//自动类型推导
	myswap<int>(a,b);//显示指定类型
	myswap(c, d);//自动类型推导
	myswap<double>(c, d);//显示指定类型
	cout << "a=" << a << endl;
	cout << "b=" << b << endl;
	cout << "c=" << c << endl;
	cout << "d=" << d << endl;
}
int main()
{
	fun1();
	return 0;
}

注意:在使用模板时,要保证模板的参数类型要一致

如果参数的数据类型是自定义的person类的数据类型,该怎么办呢?
答:可以利用模板的重载,可以为这特定的类型提供具体化的模板。

例子:

#include<iostream>
#include<string>
using namespace std;
class person
{
public:
	person(string name,int age)
	{
		m_name = name;
		m_age = age;
	}
	string m_name;
	int m_age;
};
template<typename T>
bool mycompare(T &a, T &b)
{
	if (a==b)
	{
		return true;
	}
	else
	{
		return false;
	}
}
template<> bool mycompare(person &p1, person &p2)
{
	if (p1.m_name==p2.m_name && p1.m_age==p2.m_age)
	{
		return true;
	}
	else
	{
		return false;
	}
}
void fun()
{
	person p1("Tom",10);
	person p2("Tom",10);
	bool ret = mycompare(p1,p2);
	if (ret)
	{
		cout << "p1=p2" << endl;
	}
	else
	{
		cout << "p1!=p2" << endl;
	}
}
int main()
{
	fun();
	return 0;
}

类模板

  作用:建立一个通用类,其类成员数据类型可以不具体的制定,用一个虚拟的类型来代表。

语法:

template<typename T>

  类模板中的成员函数是在调用时才被创建的

类模板对象做函数参数

有三种形式:

  • 1.指定传入类型
  • 2.参数模板化
  • 3.整个类模板化

例子:

#include<iostream>
#include<string>
using namespace std;
template<class T1,class T2>
class person
{
public:
	person(T1 name,T2 age)
	{
		this->m_name = name;
		this->m_age = age;
	}
	void myprint()
	{
		cout << "姓名: " << m_name << "   年龄: " <<m_age<< endl;
	}
	T1 m_name;
	T2 m_age;
};

1.指定传入类型(较为常用)

void work1(person<string,int> &p)
{
	p.myprint();
}

2.参数模板化

template<class T3,class T4>
void work2(person<T3,T4> &p)
{
	p.myprint();
}

3.整个类模板化

template<class T5>
void work3(T5 &p)
{
	p.myprint();
}

类模板与继承

继承有二种形式:

  • 1.子类继承的父类是模板时,在继承时一定要指定T类型
  • 子列继承的父类是模板时,如果想灵活指定父类中的T类型,子类也需要模板化

例子:

#include<iostream>
#include<string>
using namespace std;
template<class T>
class base
{
public :
	T m;
};

1.子类继承的父类是模板时,在继承时一定要指定T类型

class son1 :public base<int>
{
public:

};

2.子列继承的父类是模板时,如果想灵活指定父类中的T类型,子类也需要模板化

template<class T1>
class son2 :public base<T1>
{
public:
	son2(T1 m)
	{
		this->m = m;
		
	}
	void myprint()
	{
		cout << "姓名: " << this->m  << endl;
	}
};

类成员函数类外实现

在类外实现时:

template<class T1,class T2>
person<T1,T2>::person(T1 name,T2 age)
	{
		this->m_name = name;
		this->m_age = age;
	}

  函数名前面一定要加带有通用数据类型的类名(person<T1,T2>),如果不加通用数据类型,则是错误的;因为此类是模板类,不加通用数据类型则是普通类。

类模板分文件编写

  问题:类模板中的成员函数是在调用时才被创建的,导致分文件编写时链接不到

解决方法:

  1. main文件中直接包含“。cpp”文件
  2. 将声明和实现写在同一文件中,并更改后缀名为“.hpp”。

类模板与友元

  友元函数有两种实现方式:类内和类外
  类外在实现时比较麻烦,所以尽量使用类内实现函数友元。类内实现和普通的友元实现一样。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值