2017-07-27 87 views
0

我真的很困惑,因爲我無法很好地描述我的問題,但我相信你們中的許多人都會理解我。如何將一個值傳遞給它的參數(默認參數)

#include <iostream> 

using namespace std; 

void display(int n = 1, char c = '*'); 

int main() 
{ 
    display(); 
    display(5); 
    display('$'); 
    return 0; 
} 

void display(int n, char c) 
{ 
    for (int i = 1; i <= n; i++) 
     cout << c; 
    cout << endl; 
} 

display('$'),我想這char傳遞給它的參數c和使用n其默認值,即1。誰能告訴我如何正確地做到這一點?

+1

爲什麼不寫另一個'display(char c ='*')'函數來處理這種情況? – tadman

+0

@tadman我不確定這個行爲是否會被實現定義,但是這會使得它不清楚調用哪個函數,因爲'char'可以被提升爲'int'。 – George

+0

@SchwiftyMcSchwifulface'char'比'int'更適合'char'。 –

回答

4

你不能這樣。當你調用一個函數時,這些參數按順序從左到右匹配。這意味着display('$');將給出'$'n而不是c

儘管如此,至少在這種情況下,你可以做的是超載函數來做你想做的事情。隨着

void display(int n, char c); 
void display(int n); 
void display(char c); 
void display(); 

你可以有voidintchar超載呼叫的主要功能和隱藏的事實,你的填充中的「空白」。看起來像

void display(int n) 
{ 
    display(n, '*'); 
} 

void display(char c) 
{ 
    display(1, c); 
} 

void display() 
{ 
    display(1, '*'); 
} 

這裏的缺點是重複默認值。這使得這變得脆弱,因爲更改默認值需要您在多個地方進行更改。

+1

我會實現'display()'來調用'display(1)',所以默認的''*''字符只在一個地方被指定。或者調用'display('*')',所以默認的'1'只在一個地方指定。如果你想在一個地方指定兩個默認值,使用全局定義:'const int def_n = 1; const char def_c ='*'; void display(int n){display(n,def_c); } void display(char c){display(def_n,c); } void display(){display(def_n,def_c); }' –

2

默認參數只能從右側開始排除。因此,你的功能

void display(int n = 1, char c = '*'); 

只能被稱爲

display();  // same as display(1,'*'); 
display(5);  // same as display(5,'*'); 
display(5,'a'); 

有幾種方法來解決這個問題。在這種情況下,最簡單的(如在由tadman評論指出)將提供簡單地調用原有的功能

void display(char c) { display(1,c); }  

你一定要照顧每個超載具有不同的簽名,如您過載不能有

void display(char c = '*') { display(1,c); }  

因爲然後呼叫display()會不明確。 如果有更多的參數,它可能是有意義的聲明結構

struct Params { 
    int n; 
    char c; 
    Params() : n(1),c('*') {} 
}; 

這秤具有更多參數的更好,因爲默認設置可以按任意順序使用與否:

Params p; 
p.c = 'a'; 
display(p); 
0

我還發現了一個另一種方式是功能重新定義。

而不是

void display(int n = 1, char c = '*') {} 

我可以

void display(char c = '*', int n = 1) {} 

取代它,但函數重載是更好,因爲它會在所有的條件下工作。

相關問題