c++中模板一直都是比較複雜和難以理解的部分,對於模板的友元,有時候理解起來就更加比較麻煩。
本人在初期學習c++的時候,對於手工編寫模板的友元,也是比較棘手的。本文記錄模板友元的使用方式。
這種友元符合這種場景:
存在乙個模板類a。
另外存在乙個模板類或者模板函式b。
針對模板a的乙個例項化a,存在乙個模板b的例項化b,使得b成為a的友元。
這種場景相對來說是比較常見的,例如:
我們實現乙個模板資料管理類。
然後需要格式化輸出模板中的資料。
因此我們看一下管理類的實現:
template
<
typename t>
class
cdata
~cdata()
}private
: t* m_data;
};
如果我們要支援std::cout << cdata << std::endl
這種 操作,那麼就需要過載operator<<
操作符,使得operator<<
支援對於cdata
的格式化輸出。根據使用習慣,我們可以得知這個操作符的過載不能放入到成員函式中,因此我們需要定義如下函式:
template
<
typename t>
std::ostream&
operator
<<
(std::ostream& out,
const cdata
& data)
為了使得std::ostream& operator<<(std::ostream& out, const cdata& data)
可以訪問成員,那麼就必須設定其為友元函式。
針對cdata
類來說,std::ostream& operator<<(std::ostream& out, const cdata& data)
是一對一的關係;也就是說針對不同型別的cdata
都存在std::ostream& operator<<(std::ostream& out, const cdata& data)
例項與之對應,因此友元就應該宣告為:
friend std::ostream&
operator
<<
(std::ostream& out,
const cdata
& data)
;
整體的實現為:
template
<
typename t>
class
cdata
;template
<
typename t>
std::ostream&
operator
<<
(std::ostream& out,
const cdata
& data)
;template
<
typename t>
class
cdata
~cdata()
}friend std::ostream&
operator
<<
(std::ostream& out,
const cdata
& data)
;private
: t* m_data;};
template
<
typename t>
std::ostream&
operator
<<
(std::ostream& out,
const cdata
& data)
對於class cdata
來說,每個例項都需要對應例項的友元,因此友元必須宣告稱指定例項friend std::ostream& operator<< (std::ostream& out, const cdata& data);
(這裡的例項是針對t的)。
一對一的友元通常是比較常用的,但是通用的模板友元就比較少見了,例如乙個模板的例項,他的友元包含另外乙個模板的所有例項,可以實現為如下:
template
<
typename t>
class
cdata
;
如果我們只是宣告一對一的友元的話應該是這樣的:
template
<
typename t>
class
cmgr
;template
<
typename t>
class
cdata
;
這種情況的話更加少見,但是c++是支援的,例如
template
<
typename t>
class
cdata
;
這種情況,大部分情況下我們使用類或者函式來例項化模板。 c 遠征之模板篇 友元函式 友元類
全域性函式 友元全域性函式 成員函式 友元成員函式 1 友元關係不可傳遞 2 友元關係的單向性 3 友元宣告的形式及數量不受限制。友元宣告在類的 都可以 4 友元只是封裝的補充,是迫不得已的使用方法,可以通過設計的巧妙性,避免使用友元。它破壞了資料的封裝。include using namespac...
c 友元模板類的定義
友元概念就不羅嗦了,使用也簡單,就兩種形式 1.友元函式 friend ret type classname funname 2.友元類 friend class classname 唯一要注意的就是不管是友元函式還是友元類,定義友元關係前必須先宣告 友元類其實還是有些故事要說的,一旦類繼承起來友元...
C 中類模板與友元
類模板配合友元函式的類內和類外實現 全域性函式的類內實現 直接在類內生命友元即可 全域性函式的類外實現 需要提前讓編譯器知道全域性函式的存在 include using namespace std include 通過全域性函式來列印person的資訊 提前讓編譯器知道person類存在 templ...