C 中函式預設引數匹配問題

2021-07-16 19:55:55 字數 1871 閱讀 2232

預設引數在函式引數較多時是非常有用的.可以只傳必須的值,其它取預設值.使用方法如下:

所以只有如下使用才是合法的

(1)引數全部為預設值. void fun( int a = 1, int b = 2, int c = 3)

(2)void fun(int a , int b = 2, int c = 3)

(3)void fun(int a , int b = 2, int c) //這樣是錯誤的,如果從某處開始使用預設值,則右邊所有其他引數也必須有預設值

呼叫函式的時候傳進去的實參個數必須大於或等於無預設值的形參個數.然後匹配引數的時候是從左至右去匹配.不過這樣會存在一些問題.

例如void fun( int one , int two = 2, int three = 3);

當呼叫時如果使用者想只傳兩個引數提供one和three的值是做不到的,因為必須從左至右嚴格匹配,所有要想傳值給three,就必須給它前面的所有引數也傳值.

自然也有人想到了這問題,於是建議c++之父stroustrup增加乙個特性,可以顯式指定給第幾個引數賦值.比如呼叫上面函式時可以這樣fun(one = 1 ,three = 3),甚至還可以不按順序

fun(three = 3, one = 1)這樣使用者可以隨意指定要賦值給哪個引數,當然沒有預設值的引數肯定是要保證都有賦值的.在pl/sql中的函式呼叫就完全體現了這種思想.

不過stroustrup覺得這樣做帶來的好處不是太大,而且有些弊端,於是就沒有在c++中新增這特性.比較容易想到的弊端就是由於函式宣告和定義中的形參名字是可以不一樣的.這樣就一來靠形參名字來顯式指定傳的實參就比較麻煩了.例如宣告是void fun(int one , int two);但定義變成了void fun(int two, int one)

例如有類arwen,然後在標頭檔案中宣告函式fundefault.然後cpp檔案中定義.可以用如下兩種方式

方法(1)

int fundefault( int one , int two = 123);    //宣告

int arwen::fundefault(int one , int two)   //定義

方法(2)

int fundefault( int one , int two );

int arwen::fundefault(int one , int two = 123)

但如下是錯誤的

方法(3)

int fundefault( int one , int two = 123 );

int arwen::fundefault(int one , int two = 123)

實際上按道理講方法(3)是最直觀,最易理解的.但可能考慮到一來嘛兩個地方都重複賦值下有點麻煩,二來編譯器還要去做判斷保證兩個預設值要一致,所以就乾脆不讓這樣做了.

假如有函式

void fun(int one, int two = 2);

void fun(int one);

當這樣呼叫時fun(1);上面兩個函式都是完全匹配的.所以就有二義性了,編譯的時候會報錯的.

不過有點奇怪的是只要你是同時有函式宣告和定義時才會報錯.如果宣告和定義是在一起,都在標頭檔案中,也就是內聯函式(inline)時,上面這樣使用不會報錯.fun(1)呼叫的是void fun(int one ,int two = 2); 我是在vs中試的,不知道其他編譯器是否做同樣的處理

當然了最好我們在**中避免出現這樣的情況.實際上很多時候預設引數就是用來替代函式過載(就像上面的兩函式,當乙個函式只是比另外乙個函式的引數個數多,其他引數相同).所以設計良好的**應該是沒有必要同時存在這樣的預設引數與過載函式的

C 中 虛函式中的預設引數問題

原文 nwplei的部落格 當通過指標呼叫乙個物件的方法時,如果該方法是虛函式,則實際呼叫的是該例項的方法。當預設引數和虛函式一起出現的時候到底用哪個預設值呢?虛函式是動態繫結的,但是為了執行效率,預設引數是靜態繫結的。也就是 指標是哪種型別,就呼叫該型別對應的類中,該函式定義時的預設值。inclu...

C 中 虛函式中的預設引數問題

當通過指標呼叫乙個物件的方法時,如果該方法是虛函式,則實際呼叫的是該例項的方法。當預設引數和虛函式一起出現的時候到底用哪個預設值呢?虛函式是動態繫結的,但是為了執行效率,預設引數是靜態繫結的。也就是 指標是哪種型別,就呼叫該型別對應的類中,該函式定義時的預設值。include using names...

c 函式中的預設引數

函式的預設引數值,即在定義引數的時候同時給它乙個初始值。在呼叫函式的時候,我們可以省略含有預設值的引數。也就是說,如果使用者指定了引數值,則使用使用者指定的值,否則使用預設引數的值。void func int i 1,float f 2.0f,double d 3.0 int main void 引...