一,啞元函式:一個函式的引數只有型別沒有名字的則這個引數稱之為啞元,類似于void fun(int);
功能:1保持向前的兼容性,比方說我們需要做成一個成品,然后成品是會不斷的更新第一代第二代,當我們改進內容的時候新用戶和老用戶可能會有沖突,我們這個時候就利用啞元函式來保持兼容性;
2.做函式的區分:T operator++(){}; T oprintor++(int){};
3.使表達引數串列匹配的更加嚴格,更容易區分多載版本;
下面這個代碼就是充分驗證了更嚴格的區分了多載函式:
namespace Yayuan{ void fun(int a,double b){ cout<<"fun1:"<<a<<endl; } void fun(int a,double b,int){ cout<<"fun2:"<<a<<endl; } }//兩個函式的用法都是一樣的,只是第二個利用了啞元函式進行區分
是吧,如果沒有第二個函式最后的int系統會報錯,無法區分這兩個函式,而有了啞元函式就能幫我們實作函式的區分,啞原函式在我們真正處理C++問題的時候也會有實際的應用(運算子多載),運算子多載只能利用啞元來區分它了;
二,預設引數:如果函式的形參有預設值,當函式呼叫時沒有傳遞實參時,那么形參就使用預設值,如果呼叫函式時傳遞了實參,那么形參就使用實參的值,
注意:1.預設引數必須靠右原則,如果一個函式有多個引數,且部分引數有預設值那么預設值的引數必須靠右(在編譯期間確定引數),即使有多個也許堆在右邊;
2.如果函式的宣告和定義分開,那么預設函式就只能寫在函式宣告部分,防止報錯;
3.防止多載的沖突(函式呼叫的歧義);
4.C++中函式的規則,不接受任何引數(否則可能構成多載);
你看下面的代碼編譯正確,同時也證明了上面我說的注意事項:
#include<iostream> using namespace std; void Quesheng(short a,int b=0,double c=1.0);//只能寫在宣告部分,寫在定義部分會報錯 //一個函式可以定義一個或多個預設值
/****
void Quesheng(void){//當我使用多載的時候會發生歧義
}
****/ int main(){ Quesheng(1,12,20);//即使有預設值的引數也能賦值 Quesheng(1,12); Quesheng(1);//多載歧義 getchar(); return 0; } void Quesheng(short a,int b,double c){ cout<<a<<' '<<b<<' '<<c<<endl; }
所以說當我們使用預設值的時候是需要注意這幾方面的內容的;
三.行內函式:函式使用inline關鍵字修飾的函式叫行內函式,函式呼叫程序:
1.呼叫后立即存盤該存盤指令的記憶體地址;
2.將函式引數復制到堆疊;
3.跳到標記的函式起點的記憶體單元執行函式代碼(可能還有回傳值放入到暫存器中)再將回傳值彈出然后跳回到地址被保存的指令處;
行內的實質:就是把函式編譯好的二進制代碼替換成函式的呼叫指令(省去了呼叫開銷);
其實就是利用空間來換取時間,需要注意的是:
1.類中直接定義的函式被自動的處理成行內函式,所以一般把行內函式放到頭檔案當中去;
2.inline是一種請求,實作方式取決于編譯器,特別是當函式較大或是遞回的時候;
我簡單寫一下形式,再做遞回函式的時候定義為行內函式時是無效的,但依舊可以正常運行:
inline int Neilian(int a,int b){ return a+b; }
我現在也只是講解了這幾種函式的常用方法,以后學的比較深的話我還會繼續更新來分別把這三個函式寫成單獨的博客來介紹,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/67310.html
標籤:C++
