2012-04-26 48 views
15

我來自C#背景,最近開始學習C++。我遇到的其中一件事是pimpl成語。我爲一些大公司完成了C#開發,但從未遇到它。cim中使用pimpl習語嗎?

也許這是錯誤的,但我的理解是,它在C++中是必要的,因爲使用頭文件並且沒有部分類選項。

但是在C#中我們總是會使用類庫來構建應用程序。如果庫代碼中的某些內容發生更改,我們將重新編譯爲一個dll,並在應用程序項目中引用新的dll。

我不明白爲什麼用C++無法完成同樣的事情。 Pimpl對我來說看起來像一個醜陋的黑客。

+4

它在C++中不是「必需的」,它僅僅是爲了節省構建時間(並且在某些情況下保持二進制兼容性)。如果C++編譯/鏈接速度與C#編譯速度相同,我懷疑有人會打擾。 – ildjarn 2012-04-26 17:51:15

+1

您可能會發現感興趣的Eric Lippert的帖子,[多次傳遞](http://blogs.msdn.com/b/ericlippert/archive/2010/02/04/how-many-passes.aspx)。 – Brian 2012-04-26 18:24:11

回答

26

是在c#中使用pimpl習語嗎?

這取決於你這個成語的意思。

這個習語本質上是將一個類型的實現細節分解爲一個類,將公共表面區域分解爲一個包裝類,該類只保存到實現類的指針。

這有兩個好處。

首先,在C++中它可以提高編譯時間,因爲公共表面區域的消費者只需要解析包含公共表面區域的頭文件;他們不需要解析包含實現細節的頭文件。其次,它導致界面與實現之間非常乾淨的分離;該實現可以完全改變,而不會對消費者造成任何影響,因爲消費者從未看到實現細節。

第一個好處是無論在C#中。 C#編譯器速度很快。 (當然很大程度上是因爲語言的編譯速度很快)。

第二個好處是可以在C#中使用。在C#中,實現此模式的慣用方法是創建一個私有嵌套類,它執行「真實」工作,以及一個公共類,它只是具有公共表面區域的外觀。

的技術我特別喜歡在C#是讓公衆類基類的私有嵌套類,給基類的私有構造,以防止第三方擴展,並使用工廠模式來伸手實例的私有嵌套類。

我不明白爲什麼用C++無法完成同樣的事情。

然後,我鼓勵您嘗試編寫這樣做的C++編譯器。你要麼成功創建一個更快的C++編譯器,要麼你會發現爲什麼C++不能完成同樣的事情。你無論從哪方面都受益

+2

創建私有嵌套類有什麼好處,而不是跳過私有嵌套類,但仍然使用私有構造函數和工廠方法?難道你不能隱藏實施細節,只需將相關成員和字段設爲私有? – Brian 2012-04-26 18:37:23

+4

@布萊恩:當然,如果你有一個完全獨立的小班,那麼在一堂課中全部完成。但是如果你有一個基類BankAccount和派生類SavingsAccount和ChequingAccount,以及更多的派生類......你希望除了基類之外的所有類都是BankAccount的私有實現細節?你可以讓它們在程序集內部,或者你可以使它們對於一個類型是私有的。後者強調*給你的同事*這些類是私人執行的細節,不公平的遊戲重用。 – 2012-04-26 18:46:25

+0

好吧,有一些努力來重新思考ANSI C++的編譯模型,請參閱「C++模塊」。然而,結果至少是不確定的。如果你是一個ANSI C++庫編寫器,你可以清理現代C++(併發布源代碼),或者做一些「實用的」(可部署的,可重用的,可保護的)C++,它的邊界充滿了「黑客」而不是ANSI更多... – 2012-04-26 18:53:37

4

是的,它是(「黑客」)。它是由ANSI C++的基於文本的編譯模型引起的:編譯器需要查看代碼的文本表示以產生有用的東西。並非如此,但今天就是這樣做的。

1

正如Eric所指出的,pimpl習語有兩個目的。我只補充說第二個目的(分離接口和實現)是衆所周知的軟件設計模式之一:Bridge(也被稱爲Handle/Body我認爲)。您可以閱讀更多關於它的信息here