1.成員函數和非成員函數最大的區別在於成員函數可以是虛擬的而非成員函數不能,成員函數的優勢是能夠方便地進行動態綁定,實現多態。
說明一個函數為一個類的友元函數則該函數可以訪問此類的私有數據和方法。
2.成員函數:
--->顯式構造函數
C++中的explicit關鍵字用來修飾類的構造函數,表明該構造函數是顯式的,隱式構造函數能夠實現將該構造函數對應數據類型的數據轉換為該類對象.
class MyClass
{
public:
MyClass(int num);
}
MyClass obj=10;//convert int to MyClass
如果在構造函數前加上關鍵字explicit,上述編譯出錯.
--->靜態函數
類中,static型的成員函數,由於是類所擁有的,而不是具體對象所有的。
靜態函數屏蔽了this指針,因此,如果成員函數作為回調函數,就應該用static去修飾它。
--->虛函數:
虛函數首先是一種成員函數,它可以在該類的派生類中被重新定義並被賦予另外一種處理功能。 注意多態不是函數重載。函數重載屬於靜態綁定,虛函數實現多態是動態綁定。
--->純虛函數:
在抽象類中定義純虛函數,必須在子類實現,不過子類也可以只是聲明為純虛函數,由 子類的子類實現。
--->協變返回類型:
一般來說,一個重寫的函數與被它重寫的函數必須具有相同的返回類型。 這個規則對於”協變返回類型(covariant return type)”的情形來說有所放松.
也就是說,若B是一個類類型,並且一個基類虛擬函數返回B *,那么一個重寫的派生類函數可以返回D *, 其中的D公有派生於B(即D是一個(is-a)B).若基類虛函數返回B &,那么一個重寫的派生類
函數可以返回一個D&.
考慮如下一個shape層次結構的clone操作: Class Shape {
Public:
//…
Virtual Shape *clone () const = 0; //prototype(原型)
//…
};
Class Circle : public Shape {
Public:
//…
Circle *clone () const ;
//…
};
3、友元函數
創建友元函數的步驟:
第一步:將原型放在類聲明中,並在原型聲明前加上關鍵字friend
第二步:編寫函數定義。因為它不是成員函數,所以不要使用類的作用域。另外,不要在定義中使用關鍵字friend。
一個普通函數可以是多個類的友元函數。
一個類的成員函數也可以是另一個類的友元,從而可以使得一個類的成員函數可以操作另一個類的數據成員。
定義方法是在友元類中定義類的作用域如在類B中定義A的成員函數test為類B友元函數: friend void A::test(int &temp)
友元函數作為多個類的友元函數例:
class Country;
class Internet {
public:
Internet(char *name,char *address) // 改為:internet(const char *name , const char *address)
{
strcpy(Internet::name,name);
strcpy(Internet::address,address);
}
friend void ShowN(Internet &obj,Country &cn);//注意這里
public:
char name[20];
char address[20];
};
class Country {
public:
Country()
{
strcpy(cname,"中國");
}
friend void ShowN(Internet &obj,Country &cn);//注意這里
protected:
char cname[30];
};
void ShowN(Internet &obj,Country &cn) {
cout<<cn.cname<<"|"<<obj.name<<endl;
}
4、非成員函數
靜態函數、內聯函數和非靜態函數。