12.11 C++模板类和友元
12.11.1 非模板的友元函数
12.11.1.1 定义
friend void report(HasFriend &); // possible?
这是不可以的,因为形参没有指定类型,应该写为 HasFriend<特定类型(模板参数名或特定数据类型)> & 模板类中的static数据:要求每种模板的实例化都有自己的static成员(每种类型一个)
12.11.1.2 举例
HasFriend.h
#pragma once #ifndef HASFRIEND_H_ #define HASFRIEND_H_ #include <iostream> using std::cout; using std::endl; template <typename T> class HasFriend { private: T item; static int ct; public: HasFriend(const T& i) : item(i) { ct++; } ~HasFriend() { ct--; } friend void counts(); friend void reports(HasFriend<T>&); // template parameter }; // each specialization has its own static data member template <typename T> int HasFriend<T>::ct = 0;//这个就是对于每种类型的初始化 // non-template friend to all HasFriend<T> classes void counts() { cout << "int count: " << HasFriend<int>::ct << "; "; cout << "double count: " << HasFriend<double>::ct << endl; } // non-template friend to the HasFriend<int> 这两个是重载,类型分别是int和double void reports(HasFriend<int>& hf) { cout << "HasFriend<int>: " << hf.item << endl; } // non-template friend to the HasFriend<double> class void reports(HasFriend<double>& hf) { cout << "HasFriend<double>: " << hf.item << endl; } #endif
12.11.2 绑定模板友元函数
12.11.2.1 定义
定义绑定模板友元函数的三个步骤:
-
1.在模板类定义之前声明模板函数
-
2.将模板函数声明为模板类的友元函数
-
3.为友元函数提供定义
执行时以友元函数的模板为准,友元函数给啥类型,类模板就是啥类型
12.11.2.2 举例
HasFriendT.h
#pragma once #include <iostream> using std::cout; using std::endl; // template prototypes template <typename T> void counts(); template <typename T> void report(T&); // template class template <typename TT> class HasFriendT { private: TT item; static int ct; public: HasFriendT(const TT& i) : item(i) { ct++; } ~HasFriendT() { ct--; } friend void counts<TT>(); friend void report<>(HasFriendT<TT>&); }; template <typename T> int HasFriendT<T>::ct = 0; // template friend functions definitions template <typename T> void counts() { cout << "template size: " << sizeof(HasFriendT<T>) << "; "; cout << "template counts(): " << HasFriendT<T>::ct << endl; } template <typename T> void report(T& hf) { cout << hf.item << endl; }
12.11.3 非绑定模板友元函数
12.11.3.1 定义
友元模板函数的参数和类模板函数的参数不一样。 感觉还是友元函数模板为主导,然后友元函数是啥类型,就决定了使用的类模板类型。
12.11.3.2 举例
manyfrnd.h
#pragma once #include <iostream> using std::cout; using std::endl; template <typename T> class ManyFriend { private: T item; public: ManyFriend(const T& i) : item(i) {} template <typename C, typename D> friend void show2(C&, D&); }; template <typename C, typename D> void show2(C& c, D& d) { cout << c.item << ", " << d.item << endl; }
12.11.4 代码
main.h
#pragma once #ifndef MAIN_H_ #define MAIN_H_ #include <iostream> //输入输出 #include "HasFriend.h" //Template_Classes_and_Friends #include "HasFriendT.h" //Template_Classes_and_Friends #include "manyfrnd.h" //Template_Classes_and_Friends using namespace std; void Template_Classes_and_Friends(void) { std::cout << "\nTemplate_Classes_and_Friends Hello************************************************\n"; cout << "Non-template friends*********************************************" << std::endl; cout << "No objects declared: "; counts(); HasFriend<int> hfi1(10); cout << "After hfi1 declared: "; counts(); HasFriend<int> hfi2(20); cout << "After hfi2 declared: "; counts(); HasFriend<double> hfdb(10.5); cout << "After hfdb declared: "; counts(); reports(hfi1); reports(hfi2); reports(hfdb); cout << "Bound Template Friend Functions***************************************" << std::endl; counts<int>(); HasFriendT<int> hfi3(10); HasFriendT<int> hfi4(20); HasFriendT<double> hfdb1(10.5); report(hfi3); // generate report(HasFriendT<int> &) report(hfi4); // generate report(HasFriendT<int> &) report(hfdb1); // generate report(HasFriendT<double> &) cout << "counts<int>() output:\n"; counts<int>(); cout << "counts<double>() output:\n"; counts<double>(); cout << "Unbound Template Friend Functions*************************************" << std::endl; ManyFriend<int> hfi5(10); ManyFriend<int> hfi6(20); ManyFriend<double> hfdb2(10.5); cout << "hfi5, hfi6: "; show2(hfi5, hfi6); cout << "hfdb2, hfi6: "; show2(hfdb2, hfi6); std::cout << "\nTemplate_Classes_and_Friends Bye************************************************\n"; } #endif
main.cpp
/* Project name : _12template Last modified Date: 2022年5月6日11点33分 Last Version: V1.0 Descriptions: 模板类和友元 */ #include "main.h" int main() { cout << "模板类和友元******************************************************************" << endl; Template_Classes_and_Friends(); return 0; }
12.11.5 运行结果
模板类和友元****************************************************************** Template_Classes_and_Friends Hello************************************************ Non-template friends********************************************* No objects declared: int count: 0; double count: 0 After hfi1 declared: int count: 1; double count: 0 After hfi2 declared: int count: 2; double count: 0 After hfdb declared: int count: 2; double count: 1 HasFriend<int>: 10 HasFriend<int>: 20 HasFriend<double>: 10.5 Bound Template Friend Functions*************************************** template size: 4; template counts(): 0 10 20 10.5 counts<int>() output: template size: 4; template counts(): 2 counts<double>() output: template size: 8; template counts(): 1 Unbound Template Friend Functions************************************* hfi5, hfi6: 10, 20 hfdb2, hfi6: 10.5, 20 Template_Classes_and_Friends Bye************************************************ D:\Prj\_C++Self\_12template\Debug\_12template.exe (进程 328)已退出,代码为 0。 要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。 按任意键关闭此窗口. . .