day8-11 类模板碰到友元函数-类外实现(注意点有点多)

代码

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

//让编译器提前看到printPerson声明
//让编译器看到Person类声明
template<class T1, class T2> class Person;
template<class T1, class T2>void printPerson(Person<T1, T2> & p);


template<class T1, class T2>
class Person
{
	//友元函数类内实现  利用空参数列表 <> 来告诉编译器 模板函数的声明
	friend void printPerson<>(Person<T1, T2> & p); //普通函数 声明
	/*{
		cout << "姓名:" << p.m_Name << "  年龄: " << p.m_Age << endl;
	}*/
public:
	Person(T1 name, T2 age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}

private:
	T1 m_Name;
	T2 m_Age;
};

//类外实现,模板函数的实现
template<class T1 ,class T2>
void printPerson(Person<T1, T2> & p)
{
	cout << "姓名:" << p.m_Name << "  年龄: " << p.m_Age << endl;
}

void test01()
{
	Person<string, int> p("Tom", 10);
	printPerson(p);
}


int main(){

	test01();

	system("pause");
	return EXIT_SUCCESS;
}

代码解析

  • 一、在类内声明友元函数的时候,friend void printPerson (Person<T1, T2> & p);表示这个函数至少一个普通函数,因为模板函数或者模板类都是紧跟template<class T1, class T2>后面;所以需要让编译器强行知道这是一个模板函数的声明就需要利用空参数列表 <> 来告诉编译器 模板函数的声明,friend void printPerson<>(Person<T1, T2> & p); -------最终答案。
  • 二、接着第一个问题看,test01printPerson(p);如果普通函数和模板函数都能匹配到printPerson函数的话是会优先调用普通函数,在没有利用空列表来声明时,把friend void printPerson (Person<T1, T2> & p);当做普通函数调用,但是却找不到普通函数的实现,虽然printPerson在类外实现,但是类外实现属于模板函数的实现,所以会出错。
  • 三、下面为函数模板与普通函数的区别以及调用规则,第二个注释就是我们用到的。
  //1 、如果出现重载  优先使用普通函数调用,如果没有实现,出现错误
	//myPrint(a, b);

	//2、 如果想强制调用模板 ,那么可以使用空参数列表
	myPrint<>(a, b);

	//3、 函数模板可以发生重载
	int c = 30;
	myPrint(a, b, c);

	//4、 如果函数模板可以产生更好的匹配,那么优先调用函数模板
	char c1 = 'c';
	char d = 'd';
	myPrint(c1, d);
  • 四、因为friend void printPerson<>(Person<T1, T2> & p);类模板中成员函数 一开始不会创建出来,而是在运行时才去创建,所以在类内声明,编译器刚开始是看不到的,所以需要在外部声明一下
//让编译器提前看到printPerson声明
//让编译器看到Person类声明
template<class T1, class T2> class Person;
template<class T1, class T2>void printPerson(Person<T1, T2> & p);  
  • 五、总结
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值