天天看點

C++:11---友元函數、友元類

一、友元(friend) 

  • 概念:通過友元,打破了類的封裝性,可以通路類内的所有成員
  • 分類:友元函數、友元類

二、友元函數

            概念:友元函數是一個普通函數,不屬于類,但需要在類内表明友元關系

可通路類内所有成員,但類不可以通路友元函數内部資料

格式

  • 友元函數可以在類内聲明時,需要加上關鍵字friend
  • 友元函數可以在類外聲明,類外定義。需要加上關鍵字friend
class Cperson
{
private:
int age;
public:
friend void setPersonAge(Cperson& p,int age);
};
void setPersonAge(Cperson& p,int age) //函數在類外聲明和定義
{
p.age=age;
}
int main()
{
Cperson person;
setPersonAge(person,18);
}      
class Cperson
{
private:
int age;
public:
friend void setPersonAge(Cperson& p,int age)//友元函數在類内定義
{
p.age=age;
}
};




void setPersonAge(Cperson& p,int age);




int main()
{
Cperson person;
setPersonAge(person,18);
}      

三、友元類

  • 友元類也不屬于類成員,不擁有this指針
  • 一個類A成為另一個類B的友元類時,類A就可以通路類B的所有成員

友元類的形式分為兩種

  • 使整個類成為友元
  • 使類中的某一部分函數成為友元

使整個類成為友元

class Cb;//聲明類
class Ca
{
private:
int num;
public:
friend class Cb; //使整個類成為Ca的友元,則Cb所有的成員都可以通路Ca的所有成員
};




class Cb
{
public:
void setCaNum(Ca& a);
void Func();
};      

使類中的某一部分函數成為友元

class Cb;//聲明類
class Ca
{
private:
int num;
public:
friend void Cb::setCaNum(Ca& a);//隻有Cb的setCaNum成為Ca的友元
};




class Cb
{
public:
void setCaNum(Ca& a);
void Func();
};      

​友元關系不可被繼承​

四、友元特點

  • 單方向性:即友元可通路類,但是類不能通路友元
  • 不傳遞性:A是B的友元,C是A的友元,但C不是B的友元
  • 不繼承:在上面的友元類中有介紹

五、友元的聲明和作用域的關系

  • 使用一個友元時,要考慮到其友元的聲明和作用域的問題,請看下面代碼

class X
{
public:
friend void f(){} //友元函數在類内定義
X() {f();}   //錯誤,f()函數在下面才聲明,此處檢測不到
void g();
void h();
};
void X::g(){ return f(); }//錯誤,此時f()函數還沒有被聲明
void f(); //聲明函數
void X::h(){ return f(); } //正确,檢測到f()函數被聲明