2010-05-28 205 views

回答

0

關於C#的擴展方法:不直接。 C++對這些東西的需求較少,因爲C++支持免費函數。我從來沒有使用Objective-C,所以我不能在那裏發表評論。

1

C++沒有密封類或單個類繼承,因此在大多數情況下,您可以繼承基類。有一些創造性的方法可以使課堂不可繼承,但是它們之間並不多見。一般來說,C++沒有產生擴展方法的問題。

C不是面向對象的,所以這個問題並不適用。

+0

什麼「C#中的問題」催生了擴展方法?擴展方法僅用於支持LINQ,這是C++在任何描述中都沒有的功能。 – 2010-05-28 01:14:38

+0

密封類和單類可繼承。除了LINQ擴展方法之外,還提供了擴展類的功能的能力,這在封閉類時是不可能的(比如'string')。同樣,對繼承一個類的限制也限制了你添加mixin的能力。 – 2010-05-28 01:17:58

+3

是的,但C++中的類在沒有虛擬析構函數時被有效密封,所以我沒有看到C++如何不具有相同的問題。 – 2010-05-28 01:21:39

0

您可以使用接口嗎?擴展方法是避免子類化的一種簡單方法,但是當使用適當的OO技術時,它們會變得半無用。他們與Linq一起使用的原因是,VS團隊不必去更新那些很可能破壞很多遺留應用程序的代碼。

每MSDN: 「一般情況下,我們建議您採用擴展方法謹慎,只有當你要儘可能的客戶端代碼必須通過創建從現有派生的新類型擴展現有的類型應該這樣做。類型。」

http://msdn.microsoft.com/en-us/library/bb383977.aspx

+0

雖然有一個LinqList會讓我微笑。 – 2010-05-28 01:27:12

3

不是真的。這不是像這樣對待類的C++方式。邁爾斯認爲,最好有一個小班,以最少的一組操作,使其充分有用。如果要擴展功能集,可以添加一個實用程序名稱空間(例如名稱空間ClassUtil),該實用程序名稱空間包含在該最小類上運行的非成員實用程序函數。從任何地方向函數名稱空間添加函數都很簡單。

您可以檢查有關主題here的討論。

+1

免費功能是要走的路。 – 2010-05-28 08:05:56

23

C++具有免費函數,但有時擴展方法在將許多函數嵌套在一起時效果更好。看看這個C#代碼:

var r = numbers.Where(x => x > 2).Select(x => x * x); 

如果我們在C++中使用免費的功能寫這一點,應該是這樣的:

auto r = select(where(numbers, [](int x) { return x > 2; }), [](int x) { return x * x; }); 

這不僅是難以閱讀,但也很難寫。解決這個問題的常用方法是創建所謂的可調用函數。這些函數是通過重載|管道運算符(這只是真正的運算符)而創建的。所以上面的代碼可以這樣寫:

auto r = numbers | where([](int x) { return x > 2; }) | select([](int x) { return x * x; }); 

這是更容易閱讀和寫入。許多庫對範圍使用pipable函數,但它也可以擴展到其他類。 Boost在它們的range庫中使用它,pstade oven使用它,並且此C++ linq庫也使用它。

如果你想編寫自己的pipble函數,請解釋如何做到這一點here。但是,其他庫提供函數適配器以使其更容易。Pstade雞蛋有一個pipable adaptor,linq提供了range_extension適配器來創建一個至少爲範圍的可調函數。

使用LINQ,首先您只需建立功能函數對象是這樣的:

struct contains_t 
{ 
    template<class Range, class T> 
    bool operator()(Range && r, T && x) const 
    { return (r | linq::find(x)) != boost::end(r); }; 
}; 

然後你使用靜態初始化這樣的初始化函數:

range_extension<contains_t> contains = {}; 

然後你可以使用你的pipble功能是這樣的:

if (numbers | contains(5)) printf("We have a 5"); 
相關問題