2009-06-02 52 views
2

我有一個現有的方法(或普遍的功能),我需要增加額外的功能,但我不想在代碼中的其他地方打破任何方法的使用。例如:擴展現有API:使用默認參數或包裝函數?

int foo::bar(int x) 
{ 
// a whole lot of code here 
return 2 * x + 4; 
} 

廣泛用於基本代碼。現在我需要將4作爲一個參數,但任何已經調用foo :: bar的代碼仍然應該能夠得到它所期望的。我應該擴展和重命名舊的方法,它包裝成一個新的像

int foo::extended_bar(int x, int y) 
{ 
// ... 
return 2 * x + y; 
} 

int foo::bar(int x) 
{ 
return extended_bar(x,4); 
} 

或者我應該聲明在頭文件中的默認參數一樣

int bar(int x, int y=4); 

,只是擴展功能

int foo::bar(int x, int y) 
{ 
// ... 
return 2 * x + y; 
} 

每個變體的優缺點是什麼?

+0

似乎是對我而言的風格而不是物質。兩者都是可行的解決方案。 – Robert 2009-06-02 17:45:14

回答

7

我通常使用包裝函數(通過重載大部分時間)而不是默認參數。

的原因是,也有向後兼容性兩個層次:

  1. 源代碼級向後兼容性意味着你必須重新編譯,而不改變調用代碼,因爲新的函數簽名與舊的兼容。這兩個級別都可以實現;默認值和包裝/重載。

  2. 更強的級別是二進制級別向後兼容性,甚至可以在不重新編譯的情況下工作,例如,當你無法訪問調用代碼時。想象一下,你以二進制的形式部署你的函數,就像在一個DLL等等一樣。在這種情況下,簽名是完全相同的,使得它的工作,這不是默認值的情況 - 他們將打破這種級別的兼容性。

的包裝功能的另一個優點是 - 如果你的應用程序有任何形式的記錄 - 你可以轉儲在舊功能的警告,將在未來的版本變得過時,建議使用新一。

0

我使用C++的時間越長,我越喜歡默認的函數參數。我無法找到任何我不喜歡的具體原因,但我發現,如果我使用它們,我幾乎總是會在最終將它們移除。所以我的(主觀的)投票選擇了新的命名函數 - 名稱當然可以和舊的相同。

0

我個人認爲隱性行爲是一切邪惡根源之一。

任何爲維護者或調用者模糊被調用目標的身份應該有一個非常有力的理由,特別是如果它是主要API的一部分。

因此,我會強烈反對使用默認操作的選項。另外,我相信如果某個函數可以用不同數量的參數調用,那麼這兩個版本的函數本質上是不同的,或者它們做得太多了。這個區別應該是名字上的,並且應該比「_extended」更有意義。

+0

我同意你的最後一段,它應該是bar_with_adjustable_summand(x,y)之類的。但是如果我需要控制另外一個不變的函數中的附加參數,那麼關於你的第一個問題的解決方案是什麼? – balpha 2009-06-02 18:40:09