類模板中的友元聲明和定義

普通友元:FooBar的成員和fcn函數可以訪問Bar類的任意實例的private成員和protected成員

模板友元類FooBar

[c-sharp] view plaincopy

  1. #include<iostream>
  2. usingnamespacestd;
  3. template<classType>classBar
  4. {
  5. friendclassFooBar;
  6. Typepri;
  7. };
  8. classFooBar
  9. {
  10. public:
  11. template<typenameT>voidfoofcn(constBar<T>&b);
  12. //{cout<<b.pri<<endl;}//內部定義
  13. };
  14. template<typenameT>
  15. voidFooBar::foofcn(constBar<T>&b)
  16. {cout<<b.pri<<endl;}
  17. intmain(void)
  18. {
  19. Bar<int>bi;
  20. Bar<float>bf;
  21. FooBarfb;
  22. fb.foofcn(bi);
  23. fb.foofcn(bf);
  24. system("pause");
  25. return0;
  26. }

模板友元函數fcn

[c-sharp] view plaincopy

  1. #include<iostream>
  2. usingnamespacestd;
  3. template<classType>classBar
  4. {
  5. friendvoidfcn(constBar&b){cout<<b.pri<<endl;}//效果同下
  6. //friendvoidfcn(constBar<Type>&b){cout<<b.pri<<endl;}
  7. Typepri;
  8. };
  9. //在類外部定義不能用constBar&b形式
  10. //voidfcn(constBar&b)
  11. //{cout<<b.pri<<endl;}
  12. intmain(void)
  13. {
  14. Bar<int>bi;
  15. Bar<float>bf;
  16. fcn(bi);
  17. fcn(bf);
  18. system("pause");
  19. }

一般模板友元關係:FooBar的任意實例都可以訪問Bar的任意實例的私有成員。fcn函數相同

模板友元類FooBar

[cpp] view plaincopy

  1. #include<iostream>
  2. usingnamespacestd;
  3. template<classType>classBar
  4. {
  5. template<classT>friendclassFooBar;
  6. Typepri;
  7. };
  8. template<typenameT>classFooBar
  9. {
  10. public:
  11. template<classU>voidfoofcn(constBar<U>&b)
  12. {cout<<b.pri<<endl;}
  13. };
  14. //在外面定義
  15. /*template<classT>template<typenameU>
  16. voidFooBar<T>::foofcn(constBar<U>&b)
  17. {cout<<b.pri<<endl;}*/
  18. intmain(void)
  19. {
  20. Bar<int>bi;
  21. Bar<float>bf;
  22. FooBar<int>fbi;
  23. FooBar<float>fbf;
  24. fbi.foofcn(bi);
  25. fbi.foofcn(bf);
  26. fbf.foofcn(bi);
  27. fbf.foofcn(bf);
  28. system("pause");
  29. return0;
  30. }

模板友元函數fcn

[cpp] view plaincopy

  1. #include<iostream>
  2. usingnamespacestd;
  3. template<typenameType>classBar
  4. {
  5. template<classT>friendvoidfcn(constBar<T>&b);
  6. Typepri;
  7. };
  8. template<typenameT>
  9. voidfcn(constBar<T>&b)
  10. {cout<<b.pri<<endl;}
  11. intmain(void)
  12. {
  13. Bar<int>bi;
  14. Bar<float>bf;
  15. fcn(bi);
  16. fcn(bf);
  17. system("pause");
  18. }

函數定義在模板內部會導致重複定義

[cpp] view plaincopy

  1. #include<iostream>
  2. usingnamespacestd;
  3. template<typenameType>classBar
  4. {
  5. template<classT>friendvoidfcn(constBar<T>&b){cout<<b.pri<<endl;}
  6. Typepri;
  7. };
  8. intmain(void)
  9. {
  10. Bar<int>bi;
  11. //Bar<float>bf;
  12. fcn(bi);
  13. //fcn(bf);
  14. system("pause");
  15. }

3.特定的模板友元關係:Bar實例只與有相同模板實參的FooBar版本是友元

3.1

模板友元類FooBar

[cpp] view plaincopy

  1. #include<iostream>
  2. usingnamespacestd;
  3. //需要前置聲明,編譯器將友元聲明當作類的聲明
  4. template<classT>classFooBar;
  5. template<classType>classBar
  6. {
  7. friendclassFooBar<Type>;
  8. Typepri;
  9. };
  10. template<classT>classFooBar
  11. {
  12. public:
  13. voidfoofcn(constBar<T>&b);//{cout<<b.pri<<endl;}//在內部定義
  14. };
  15. template<classT>
  16. voidFooBar<T>::foofcn(constBar<T>&b)
  17. {cout<<b.pri<<endl;}
  18. intmain(void)
  19. {
  20. Bar<int>bi;
  21. Bar<float>bf;
  22. FooBar<int>fbi;
  23. FooBar<float>fbf;
  24. fbi.foofcn(bi);
  25. //fbi.foofcn(bf);//error
  26. //fbf.foofcn(bi);//error
  27. fbf.foofcn(bf);
  28. system("pause");
  29. return0;
  30. }

模板友元函數fcn

[cpp] view plaincopy

  1. #include<iostream>
  2. usingnamespacestd;
  3. template<classT>classBar;
  4. template<classT>voidfcn(constBar<T>&);//需要前置聲明
  5. template<typenameType>classBar
  6. {
  7. //friendvoidfcn<Type>(constBar<Type>&b);//模板特化
  8. friendvoidfcn<>(constBar<Type>&b);//兩種聲明均可
  9. Typepri;
  10. };
  11. template<classT>
  12. voidfcn(constBar<T>&b)
  13. {cout<<b.pri<<endl;}
  14. intmain(void)
  15. {
  16. Bar<int>bi;
  17. Bar<float>bf;
  18. //fcn<float>(bi);//函數模板的類型可以和形參的模板類型不一致
  19. fcn<int>(bi);
  20. fcn(bi);
  21. fcn(bf);
  22. fcn<float>(bf);
  23. //fcn<int>(bf);
  24. system("pause");
  25. }

另一種寫法,在模板類內部定義,調用fcn需要顯示指定模板實參

[cpp] view plaincopy

  1. #include<iostream>
  2. usingnamespacestd;
  3. template<typenameType>classBar
  4. {
  5. template<classT>friendvoidfcn(constBar<Type>&b){cout<<b.pri<<endl;}
  6. Typepri;
  7. };
  8. intmain(void)
  9. {
  10. Bar<int>bi;
  11. Bar<float>bf;
  12. fcn<float>(bi);//函數模板的類型可以和形參的模板類型不一致
  13. fcn<int>(bi);
  14. //fcn(bf);//error//調用時要顯示指定函數模板類型
  15. fcn<int>(bf);
  16. system("pause");
  17. }

3.2特定實例

模板友元類FooBar

[cpp] view plaincopy

  1. #include<iostream>
  2. usingnamespacestd;
  3. //需要前置聲明
  4. template<classT>classFooBar;
  5. template<classType>classBar
  6. {
  7. friendclassFooBar<float>;
  8. Typepri;
  9. };
  10. template<typenameT>classFooBar
  11. {
  12. public:
  13. //foofcn(constBar<T>&b)只能訪問Bar的對應類型,不能訪問所有類型
  14. //voidfoofcn(constBar<T>&b){cout<<b.pri<<endl;}
  15. template<classU>voidfoofcn(constBar<U>&b){cout<<b.pri<<endl;}
  16. };
  17. intmain(void)
  18. {
  19. Bar<int>bi;
  20. Bar<float>bf;
  21. FooBar<int>fbi;
  22. FooBar<float>fbf;
  23. //fbi.foofcn(bi);
  24. //fbi.foofcn(bf);//error
  25. fbf.foofcn(bi);//如果定義為foofcn(constBar<T>&b),則fbf沒訪問bi私有變數的許可權
  26. fbf.foofcn(bf);
  27. system("pause");
  28. return0;
  29. }

模板友元函數fcn

[cpp] view plaincopy

  1. #include<iostream>
  2. usingnamespacestd;
  3. template<classT>classBar;
  4. template<classT>voidfcn(constBar<T>&);//需要前置聲明
  5. template<typenameType>classBar
  6. {
  7. friendvoidfcn<float>(constBar<float>&b);
  8. Typepri;
  9. };
  10. template<classT>
  11. voidfcn(constBar<T>&b)
  12. {cout<<b.pri<<endl;}
  13. intmain(void)
  14. {
  15. Bar<int>bi;
  16. Bar<float>bf;
  17. //fcn<float>(bi);//函數模板的類型可以和形參的模板類型不一致
  18. //fcn<int>(bi);
  19. //fcn(bi);
  20. fcn(bf);//只接受Bar<float>實參
  21. fcn<float>(bf);
  22. //fcn<int>(bf);
  23. system("pause");
  24. }

可以將fcn定義為非模板

[cpp] view plaincopy

  1. #include<iostream>
  2. usingnamespacestd;
  3. template<typenameType>classBar
  4. {
  5. friendvoidfcn(constBar<float>&b);
  6. Typepri;
  7. };
  8. voidfcn(constBar<float>&b)
  9. {cout<<b.pri<<endl;}
  10. intmain(void)
  11. {
  12. Bar<int>bi;
  13. Bar<float>bf;
  14. //fcn(bi);
  15. fcn(bf);//只接受Bar<float>實參
  16. //fcn<float>(bf);//fcn不是模板類函數
  17. system("pause");
  18. }

非類型形參的模板友元

模板友元類FooBar

[cpp] view plaincopy

  1. #include<iostream>
  2. usingnamespacestd;
  3. template<inthi>classBar
  4. {
  5. private:
  6. friendclassFooBar;
  7. intpri;
  8. public:
  9. Bar():pri(hi){}
  10. };
  11. classFooBar
  12. {
  13. public:
  14. template<inthi>voidfoofcn(constBar<hi>&b){cout<<b.pri<<endl;}
  15. };
  16. intmain(void)
  17. {
  18. Bar<34>b;
  19. Bar<21>b1;
  20. FooBarfb;
  21. fb.foofcn(b);
  22. fb.foofcn(b1);
  23. system("pause");
  24. return0;
  25. }

模板友元函數fcn

[cpp] view plaincopy

  1. #include<iostream>
  2. usingnamespacestd;
  3. template<inthi>classBar
  4. {
  5. private:
  6. intpri;
  7. public:
  8. Bar():pri(hi){}
  9. friendvoidfcn(constBar<hi>&b){cout<<b.pri<<endl;}
  10. };
  11. intmain(void)
  12. {
  13. Bar<34>b;
  14. Bar<21>b1;
  15. fcn(b);
  16. fcn(b1);
  17. system("pause");
  18. return0;
  19. }

外部定義

[cpp] view plaincopy

  1. #include<iostream>
  2. usingnamespacestd;
  3. template<inthi>classBar;
  4. template<inta>voidfcn(constBar<a>&);
  5. template<inthi>classBar
  6. {
  7. private:
  8. intpri;
  9. public:
  10. Bar():pri(hi){}
  11. friendvoidfcn<>(constBar<hi>&b);//定義在外部需要特化聲明
  12. };
  13. template<inthi>
  14. voidfcn(constBar<hi>&b)
  15. {cout<<b.pri<<endl;}
  16. intmain(void)
  17. {
  18. Bar<34>b;
  19. Bar<21>b1;
  20. fcn(b);
  21. fcn(b1);
  22. system("pause");
  23. return0;
  24. }

函數定義在類內部,每次實例化都會生成相應的版本,所以有時會導致重複定義的錯誤,但有些友元只能定義在模板的內部

推薦閱讀:

明星情侶分手聲明撰寫指南
時事資訊:聲明公證不能替代繼承公證
論聲明與修行的關係
霆鋒單方面發離婚聲明 柏芝情緒失控求複合?
資中筠:我的一個聲明

TAG:定義 | 模板 | 聲明 |