第十天:友元函數和友元類使得程序員在不放棄私有數據安全性的情況下,對特定的函數或類進行訪問。
要想通過一個打印函數打印類中的數據成員,要麼函數是類中的一個成員,要麼是友元函數。注意友元函數不是類成員,而是位於類作用域外的函數。定義友元函數時只需將它的函數原型插入類定義,象聲明成員函數一樣,再在函數原型前加入關鍵字friend即可。類本身決定友元的存在。友元函數是非成員函數,所以它無法通過this指針獲得一份拷貝,因此必須給友元函數傳遞一個對象變量,這一點和其他非成員函數是一樣的,不同的是友元函數可以訪問類的私有數據。
友元函數必須帶有某類變量為參數,才能獲取對象數據並對其操作。
一個獨立的友元函數可以訪問多個類的數據,但必須同時為這多個類的友元。//注意:向前引用是類的原型說明。
當一個類需要訪問另一個類的某幾個或全部私有數據或是私有成員函數時,將其聲明為友元類。友元類是一個單獨的類它可以訪問另一個類中的所有成員。友元類中含有一個成員,它的類型是聲明了這個友元類的類。即使一個類不是友元類,它的成員也可能是其它類的對象,但是該類將無法訪問其對象成員的私有成員。
file://一個例子:
#include
#include
#include
class Boyssoftball;//類聲明,因為另一個類要引用到它,如友元函數,所以必須先定義。
class Girlssoftball{
char name[25];
int age;
float batavg;
public:
void init(char N[],int A,float B);
friend void prdata(const Girlssoftball p1g,const Boyssoftball p1b);
};
void Girlssoftball::init(char N[],int A,float B){
strcpy(name,N);
age=A;
batavg=B;
}
class Boyssoftball{
char name[25];
int age;
float batavg;
public:
void init(char N[],int A,float B);
friend void prdata(const Girlssoftball p1g,const Boyssoftball p1b);
};
void Boyssoftball::init(char N[],int A,float B){
strcpy(name,N);
age=A;
batavg=B;
}
main()
{
Girlssoftball *Gplayer[3];
Boyssoftball *Bplayer[3];
for(int i=0;i<3;i++){
Gplayer[i]=new Girlssoftball;
Bplayer[i]=new Boyssoftball;
}
Gplayer[0]->init("stacy",12,1.34);
Gplayer[1]->init("suci",13,2.34);
Gplayer[2]->init("ketey",12,3.434);
Bplayer[0]->init("tom",12,4.434);
Bplayer[1]->init("jone",12,5.504);
Bplayer[2]->init("hunter",13,6.496);
for(int n=0;n<3;n++){
prdata(*Gplayer[n],*Bplayer[n]);}
for(int j=0;j<3;j++){
delete Gplayer[j];
delete Bplayer[j];
}
return 0;
}
void prdata(const Girlssoftball p1g,const Boyssoftball p1b){
cout< cout<<"player name:"< cout<<"player age:"< cout<<"player average:"< cout<<"player name:"< cout<<"player age:"< cout<<"player average:"< }
第十一天和第十二天:
當需要對自定義數據類型進行類似於對內部數據類型進行內部操作時使用操作符重載函數。
盡可能的編寫全面的operator...()函數,以便操作符兩邊出現不同數據類型組合時,操作符重載依舊有效。
再操作符重載函數中不要將多余的參數傳遞進去,VC++象處理其它成員函數一樣負責傳送接受this指針。
不要遠離操作符原來的意思。
在重載操作符兩邊放置同名的類變量,可以使得一個類變量為空。
可以使用友元函數編寫要把內部數據類型和自定義數據類型進行操作的,操作符重載函數。
如果將與復合操作符等價的操作符重載了,最好也重載該復合操作符。如如果重載了*最好將*=也重載。這樣做的好處是有助於豐富類的功能。
在重載復合操作符時一定要返回一個this指針的間接引用。這種操作符必須返回一個左邊操作符被修改的備份。
不能精確的比較兩個浮點數的值。不要輕易重載關系比較符。如與&&或||。
如果要把內部數據作為左操作符而自定義數據類型作右操作符時,為了防止this指針的干擾,又為了能訪問類中的私有成員,所以必須用友元函數。
重載遞增及遞減操作符也必須返回this指針。
學習了輸入<<和輸出>>操作符的重載,通過編寫簡單的operator<<(),掌握了一種方法,將main()函數的煩瑣細節除去,交給自定義的類去處理。istream和ostream的對象是和輸入輸出流數據相連的,由於能夠存取流中數據,就還可以編寫I/O操作算子函數。
下標符號也可以重載,使得余下的程序可以訪問單個的成員或成員的數組元素。使用下標符號能創建安全的數組,能實現上下界自檢。