C++函數區別於C函數主要有四個方面的進階特性:
一、重載(overloaded)、內聯(inline)、const和virtual四種新機制。
重載函數條件:1.函數名相同,2,同一個範圍(即同時為某個類的成員函數)3.參數個數或類型不同
注意:1.函數僅傳回型別不同這不是函數重載,編譯會報錯
2.相同函數名作用於不同而非函數重載 例如:
void Print(…); // 全域函數
class A
{…
void Print(…); // 成員函數
} 不論兩個Print函數的參數是否不同,如果類的某個成員函數要調用全域函數Print,為了與成員函數Print區別,全域函數被調用時應加‘::’標誌。如
::Print(…); // 表示Print是全域函數而非成員函數
1.編譯器怎樣區別重載函數?
編譯器在編譯時間根據重載函數參數的類型以及個數不同做個標示以示區別。
2.重載與重寫即覆蓋(override)的區別:覆蓋應用在繼承關係的父類與子類之間,覆蓋的函數必須由virtual 關鍵字標示 例如:
函數Base::f(int)與Base::f(float)相互重載,而Base::g(void)被Derived::g(void)覆蓋。
#include
class Base
{ public:
void f(int x){ cout << "Base::f(int) " << x << endl; }
void f(float x){ cout << "Base::f(float) " << x << endl; }
virtual void g(void){ cout << "Base::g(void)" << endl;}
}; class Derived : public Base
{ public:
virtual void g(void){ cout << "Derived::g(void)" << endl;}
}; void main(void)
{ Derived d;
Base *pb = &d;
pb->f(42); // Base::f(int) 42
pb->f(3.14f); // Base::f(float) 3.14
pb->g(); // Derived::g(void)
}
二.內斂與宏的區別:
宏由前置處理器對宏進行替代,而內嵌函式通過編譯器控制來實現。兩者都能提高程式運行效率
1. 程式在編譯時間,編譯器會將宏引用的地方替換成定義的語句塊,即將引用的代碼展開:
宏有兩個缺點:1.紅不能訪問私人屬性
2.宏容易產生函數二義性,例如:
例如下面這個宏:
#define MAX(a, b) a>b?a:b
當我們這樣使用宏時,沒有什麼問題: MAX( num1, num2 ); 因為宏展開後變成 num1>num2?num1:num2 ;。 但是,如果是這樣調用的, MAX( 17+32, 25+21); 呢,編譯時間出現錯誤,原因是,宏展開後變成: 17+32>25+21?17+32:25+21 , Woh ,這是什麼啊?
所以,宏在使用時,參數一定要加上括弧,上述的那個例子改成如下所示就能解決問題了。
#define MAX( (a), (b) ) (a)>(b)?(a)b)
即使是這樣,也不這個宏也還是有 Bug ,因為如果我這樣調用 MAX(i++,j++); , 經過這個宏以後, i 和 j 都被累加了兩次,這絕不是我們想要的。所以,在宏的使用上還是要謹慎考慮,因為宏展開是的結果是很難讓人預料的。而且雖然,宏的執行很快(因為沒有函數調用的開銷),但宏會讓原始碼澎漲,使目標檔案尺寸變大,(如:一個 50 行的宏,程式中有
1000 個地方用到,宏展開後會很不得了),相反不能讓程式執行得更快(因為執行檔案變大,運行時系統換頁頻繁)。
2.內嵌函式必須和函數體一起申明才有效
像這樣的申明 Inline Tablefunction(int I) 是沒有效果的,編譯器只是把函數作為普通的函 數申明,我們必須定義函數體。
Inline tablefunction(int I) {return I*I};
這樣我們才算定義了一個內嵌函式。我們可以把它作為一般的函數一樣調 。但是執行速度確比一般函數的執行速度要快。 我們也可以將定義在類的外部的函數定義為內嵌函式 ,比如:
Class TableClass{
Private:
Int I,j;
Public:
Int add() { return I+j;};
Inline int dec() { return I-j;}
Int GetNum();
}
inline int tableclass::GetNum(){
return I;
}
上面申明的三個函數都是內嵌函式。在 C++ 中,在類的內部定義了函數體的 函數,被預設為是內嵌函式。而不管你是否有 inline 關鍵字。 內嵌函式在
C++ 類中,應用最廣的,應該是用來定義存取函數。我們定義的 類中一般會把資料成員定義成私人的或者保護的,這樣,外界就不能直接讀寫我 們類成員的資料了。 對於私人或者保護成員的讀寫就必須使用成員介面函數來進行。如果我們把 這些讀寫成員函數定義成內嵌函式的話,將會獲得比較好的效率。
Class sample{
Private:
Int nTest;
Public:
Int readtest(){ return nTest;}
Void settest(int I) {nTest=I;}
}
當然,內嵌函式也有一定的局限性。就是函數中的執行代碼不能太多了 ,如 果,內嵌函式的函數體過大,一般的編譯器會放棄內聯方式,而採用普通的方式 調用函數。這樣,內嵌函式就和普通函數執行效率一樣了。
註:寫此博文有參考其他博文