C 過載函式分析

2021-07-22 05:49:39 字數 4256 閱讀 5930

c++過載函式的定義:同一作用域的多個函式,如果具有相同函式名而同時具有不同的形參列表,它們可以稱為過載函式。

1)過載函式也是函式,所以需要函式名;函式名只是為了幫助編譯器判斷呼叫的是哪個函式而已。

2)相同函式名正是過載函式引入的目的,對於一系列類似的操作省去為函式起名和記住函式名的麻煩,簡化了程式實現,且使程式更容易理解。

過載函式必須在同一作用域的原因是:c++有區域性宣告遮蔽全域性宣告的特性。這樣如果在區域性作用域有乙個與外層作用域的過載函式同名的函式,該函式將遮蔽那些外層的過載函式。

例子如下:

void func(const string &);

void func(const double); //過載func

void f(int ival)

但是如果將區域性宣告拿到函式外,位於同一作用域後,過載函式ok。
void func(const string &);

void func(const double); //過載func

void func(int); //過載func

void f(int ival)

**經過編譯後會生成符號(symbol)表,函式呼叫是通過符號表中函式符號名來實現的(注意:函式名不同於函式符號名)。 c++中的函式符號名由函式名形參列表共同決定(函式符號名與函式返回值沒有任何關係),形參列表包括形參個數和形參型別

過載函式正是利用c++函式符號名這種特性來實現的,這樣相同函式名如果使用不同形參列表,會生成不同函式符號名(不會出現重複定義的問題)。

判斷不同形參列表時注意事項(注意下面people是類):

(1)形參名僅是幫助文件,不會影響形參列表

void func(const people &a); //形參名a

void func(people &);

(2)typedef僅提供別名,不會建立新的型別

typedef people p //p是people的別名

void func(const people &);

void func(const p &);

(3)呼叫帶預設實參函式時,編譯器可以忽略預設實參(這意味著使用者可以給定實參也可以不給定),預設實參不影響引數個數

void func(const people1 &, const people2 &);

void func(const people1 &, const people2 & = 」「); //沒有改變引數個數

(4)const形參

a)對於函式值傳遞形參場合,const與非const是等價的形參;

void func(people1,people2);

void func(const people1, const people2);

b)對於函式引用傳遞形參場合,const與非const是不同的形參;

void func(people &);

void func(const people &); //新函式,是func的過載函式

const people a(1,2);

people b;

func(a);//呼叫func(const people &)

func(b);//呼叫func(people &)

c)對於函式指標傳遞形參場合,指向const物件與指向非const物件是不同的形參;

注意:基於指標本身是否為const不能實現函式過載

void func(int *);

void func(int * const); //屬於重複宣告

匹配的結果有3種可能

1)編譯器找到最佳匹配函式,生成呼叫函式**;

2)編譯器找不到匹配函式,編譯出錯;

3)找到多個匹配函式,但是沒有乙個是最佳匹配函式,呼叫具有二義性;

void func();

void func(int);

void func(int, int);

void func(double, double = 1.2);

func(1.35); //呼叫func(double, double = 1.2)

1)查詢候選函式

與被呼叫函式同名的函式都可以稱為候選函式。上面例子中候選函式有4個。

2)確定可行函式

可行函式需要滿足2個條件:

a)被調函式實參與函式形參個數相同;

b)被調函式實參與函式引數型別匹配,或者可以通過隱式轉化為型別匹配;

3)決定最佳匹配

最佳匹配原則:

a)實參與形參型別精確匹配優於需要型別轉化後的匹配

b)多引數最佳匹配特點

i)每個實參匹配不劣於其它可行函式;

ii)至少有乙個實參優於其它可行函式;

func(1,1.5)呼叫分析:

第一步候選函式:4個

第二步:可行函式func(int,int)和func(double,double)

第三步:最佳匹配,只看實引數1精確匹配func(int,int),再看實參2精確匹配的是func(double,double),2個函式形參優劣相當這樣找不出最佳匹配,出現了」二義性「。

解決二義性辦法是顯式強制型別轉換,但是強制型別轉換不是最好的,要避免;出現這樣情況表明形參設計不合理。

func(static_cast(1), 1.5)//呼叫func(double,double)

func(1, static_cast(1.5)) //呼叫func(int,int)

實參型別轉換分為4級:

1)精確匹配,實參與形參型別一致

2)通過型別提公升實現匹配;

3)通過標準轉換實現匹配;

4)通過類型別轉換實現匹配;

注意:

a)型別提公升實現匹配優於標準轉換實現的匹配

extern void func(long);

extern void func(float);

func(3.14); //造成二義性,因為都是使用標準轉換,沒有說哪個更優

b)較小整型提公升為int型

extern void func(int);

extern void func(short);

func('c'); //char提公升為int,匹配到函式func(int)

c)列舉物件只能用同型別列舉物件或者列舉成員初始化

enum test ;

extern void func(test);

extern void func(int);

void main()

d)列舉值可以傳遞給整型形參,整型值不能傳遞給列舉形參

enum test ;

extern void func(int);extern void func(unsigned char);

unsigned char uchar = 130;

func(t2); //呼叫

func(uchar);//呼叫

c++ primer

OSTaskCreate()函式分析

int8u ostaskcreate void task void pd void p arg,os stk ptos,int8u prio 函式返回乙個8位的整型數,呼叫該函式需要四個引數。第乙個引數乙個指標,也就是使用者 的首位址,在平時使用中我們把自己建立的任務的名字作為這個引數就可以了 第三...

getopt函式分析

函式getopt主要用於拆分命令列引數,用這個函式就不自己寫命令列引數解析程式了,以下 摘自tcpdump原始碼,對這個函式比較感興趣,故對此進行分析注釋,因水平實在不敢恭維,不足之處希望能一起 函式getopt 有三個引數,nargc,nargv就是命令列傳過來的argc和argv字串ostr,它...

uCOS OSTaskCreate()函式分析

int8u ostaskcreate void task void pd void p arg,os stk ptos,int8u prio 函式返回乙個8位的整型數,呼叫該函式需要四個引數。第乙個引數乙個指標,也就是使用者 的首位址,在平時使用中我們把自己建立的任務的名字作為這個引數就可以了 第三...