c++之友元函式和友元類
阿新 • • 發佈:2018-11-16
c++友元函式一些見解
1、為什麼要引入友元函式:在實現類之間資料共享時,減少系統開銷,提高效率
具體來說:為了使其他類的成員函式直接訪問該類的私有變數
即:允許外面的類或函式去訪問類的私有變數和保護變數,從而使兩個類共享同一函式
優點:能夠提高效率,表達簡單、清晰
缺點:友元函式破環了封裝機制,儘量不使用成員函式,除非不得已的情況下才使用友元函式。
2、什麼時候使用友元函式:
1)運算子過載的某些場合需要使用友元。
2)兩個類要共享資料的時候
3、怎麼使用友元函式:
友元函式的引數:
因為友元函式沒有this指標,則引數要有三種情況: 1、 要訪問非static成員時,需要物件做引數;--常用(友元函式常含有引數) 2、 要訪問static成員或全域性變數時,則不需要物件做引數 3、 如果做引數的物件是全域性物件,則不需要物件做引數
友元函式的位置:
因為友元函式是類外的函式,所以它的宣告可以放在類的私有段或公有段且沒有區別。
友元函式的呼叫:
可以直接呼叫友元函式,不需要通過物件或指標
- 普通的友元函式
#include<iostream> using namespace std; class Date { friend ostream& operator<<(ostream& _cout, const Date& d); public: Date(int year, int mouth, int day) :_year(year) , _mouth(mouth) , _day(day) {} private: int _year; int _mouth; int _day; }; ostream& operator<<(ostream& _cout, const Date& d) { _cout << d._year << ":" << d._mouth << ":" << d._day << endl; return _cout; } int main() { Date d(2018, 11, 2); cout << d << endl; return 0; }
- 上面的程式碼我過載了 << 運算子。這裡必須放在類外來定義,如果放在類中來定義的話,我的主函式中 cout<< d<< endl 只能這樣寫了:d<<cout<<endl;
- 為什麼呢?來看看下面程式碼。
- 我的定義寫在類中,那麼會出現什麼情況呢?操作符 << 只需要傳兩個引數,那麼在類中這樣定義就會傳了三個引數,不要this 指標哦。有人說,那不傳 ostream& _cout 不就好了,啊哈,行啊,那麼第一個引數就是const Date& d。最後呼叫的就要是 d<<cout;這樣子了。所以友元函式是必須的。
class Date
{
ostream& operator<<(ostream& _cout, const Date& d)
{
_cout << d._year << ":" << d._mouth << ":" << d._day << endl;
return _cout;
}
public:
Date(int year, int mouth, int day)
:_year(year)
, _mouth(mouth)
, _day(day)
{}
private:
int _year;
int _mouth;
int _day;
};
總結:友元函式可以直接訪問類的私有成員,它是定義在類外部的普通函式,不屬於任何類,但需要在類的內部宣告,宣告時需要加friend關鍵字。
問題1:友元函式能不能用const修飾?
回答:不能,在類中,const 修飾函式是修飾函式的什麼?當然是類函式中的this指標了,那麼友元函式有沒有this指標呢?當然沒有this指標了,所以友元函式不能用const修飾。
友元函式可訪問類的私有成員,是不是類的成員函式?
回答:不是,可以這樣理解,友元函式是類的好朋友,那麼類中的私有成員我允許我的朋友來訪問。
友元函式需要放在類的那裡來宣告呢?public?private?還是?
回答:友元函式可以在類定義的任何地方宣告,不受類訪問限定符限制
函式A是類A的友元函式,那麼函式還能是類B 的友元函式呢?
回答:你肯定不止一個朋友吧。一個函式可以是多個類的友元函式。
除了友元函式,還有友元類。
c++.h
#include<iostream>
using namespace std;
class Date
{
friend class Time;
public:
Date(int,int,int);
void Print();
private:
int _year;
int _mouth;
int _day;
};
class Time
{
friend class Date;
public:
Time(int ,int ,int);
void Print();
private:
int _hour;
int _minut;
int _second;
};
c++.cpp
#include<iostream>
#include"c++.h"
using namespace std;
Date::Date(int year = 1990, int mouth = 1, int day = 1)
:_year(year)
, _mouth(mouth)
, _day(day)
{}
void Date::Print()
{
Time t(11,101,10);
cout << _year << "-" << _mouth << "-" << _day << t._hour << "-" << t._minut << "-" << t._second << endl;
}
Time::Time(int hour = 11, int minut = 10, int second = 10)
:_hour(hour)
, _minut(minut)
, _second(second)
{}
void Time::Print()
{
Date d(100, 101, 102);
cout << d._year << "-" << d._mouth << "-" << d._day << _hour << "-" << _minut << "-" << _second << endl;
}
void Func()
{
Date d(100,101,102);
d.Print();
Time t(10,11,12);
t.Print();
}
int main()
{
Func();
return 0;
}
- 這個要看清楚友元函式必須要在標頭檔案中宣告,在另一個檔案中來定義。為什麼?你自己放在一個檔案中你就知道了,我說不清楚。
- 上面的例子是個友元類,友元類的所有成員函式都可以是另一個類的友元函式,都可以訪問另一個類中的非公有成員。
注意:
- 友元的優缺點
- 優點:提高了程式執行效率
- 缺點:破壞了類的封裝性和隱藏性
- 友元關係是單向的,不具有交換性。
- 比如上述Time類和Date類,在Time類中宣告Date類為其友元類,那麼可以在Date類中直接訪問Time 類的私有成員變數,但想在Time類中訪問Date類中私有的成員變數則不行。
- 友元關係不能傳遞 如果B是A的友元,C是B的友元,則不能說明C時A的友元。