一、友元(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()函數被聲明