2013-05-08 46 views
0

我有以下問題需要解決。在編譯時決定構造對象

我有組件A.此組件有一些子組件 - B,C,D。使用cmake我正在構建或不構建B,C,D組件。這取決於當前的平臺配置。我的cmake系統正在生成可執行的makefile(對於A組件),用於僅鏈接那些在給定cmake運行中使用的組件。如果構建組件B,則會將其添加到可執行文件中(如果沒有) - 未鏈接。與其他 - C,D相同。

所有這些B,C,D組件都提供了A組件中使用的接口的一些實現。這個A組件應該管理由B,C,D創建的對象,並在適當的時候使用適當的對象將這些對象保存在某個映射中。

問:

我要實現一些簡單的和可靠的機制,將這些對象自動實現A接口,同樣因爲它現在是帶有鏈接 - 鏈接只是模塊,建成。與這些對象相同 - 我希望只有在編譯時纔將它們註冊到A組件中。

我很難解釋它。這個想法很容易 - 在編譯時建立這些對象的一些映射。只有已編譯的組件才能將其對象傳送到此地圖

+1

您可以使用makefile/cmake系統設置的預處理器指令來解決此問題。例如,如果編譯組件B並且在編譯A時應該包含組件B,則可以使用指令(如#ifdef COMPILED_B)在必要時在B中包含對B的支持。 – 2013-05-08 13:47:36

+0

是的,這是可能的,但我想在源代碼中避免#ifdef。我只是想知道其他人是如何以更復雜的方式來做這件事的。 – user2301299 2013-05-08 14:29:12

回答

1

我已經使用類似於Objective-C和Smalltalk實現方法的設計。

在C++中,方法==成員函數並且必須在編譯時定義。所以,儘管接口可以通過預處理器等機制進行擴展,但是相同的配置也必須影響該類的任何客戶端,否則它們將無法鏈接。

所以我使用消息傳遞系統來調用對象上的方法。因此,如果是主類,並在C和d而非B編譯,那麼A的消息處理器將只具有由C和D.

這種類型的設計確實需要有註冊的處理程序響應消息某種消息系統。有許多現有的系統,如谷歌協議緩衝區和Apache Thrift。我選擇設計一個,因爲我想要比大多數現有系統允許的更多運行時配置(許多這些消息傳遞系統都包含IDL編譯器)。

但是,它確實使我能夠接近OO領域,而不是C++通常允許的混合範式語言。

+0

因此,在你的情況下,已編譯(C,D)的組件必須擁有一些全局範圍(在進程啓動時初始化)的對象,它們將自己註冊爲某個全局消息調度程序的處理程序?他們是從他們的建設者那裏做的? – user2301299 2013-05-08 21:04:28

+1

A的構造函數搜索共享對象的路徑。如果它們存在,則加載它們並調用初始化函數(所有組件上的標準名稱)。初始化程序通過註冊方法名稱和相關地址將其功能注入消息傳遞系統。作爲消息的一部分,參數作爲鍵值對攜帶。可以查詢新組件的消息API以獲取命令,參數,單位,限制/範圍和一些描述的列表。這一點有點複雜,但針對的是大型分佈式系統的簡單維護。 – 2013-05-08 21:14:28

+0

在一個特定示例中,構造函數被傳遞一個字符串,該字符串表示此項目的組件目錄的路徑。然後操作系統的API用於定位和加載共享對象(用於Windows版本的DLL)並動態鏈接其代碼。這些對象包括其作爲消息處理程序實現的功能以及可將其功能注入消息傳遞系統的init函數。指向消息客戶端的指針被傳遞給init函數,以便它可以進行註冊調用。 – 2013-05-08 21:23:46