2013-04-16 60 views
3

爲了啓動我的C++程序,我需要閱讀一些配置,例如IP地址,端口號,文件路徑......這些設置可能會頻繁更改(每週或每天!),因此將它們硬編碼到源文件中並不是一個好主意。在大型C++項目中處理配置的最佳方法

經過一番研究,我感到困惑是否有從文件中加載配置設置的最佳實踐,並取得這些CONFIGS提供給其他類/模塊/ *。在同一個項目CPP。

static is bad;單身是(一個反模式?)那麼,我們還有什麼其他選擇?或者,也許「配置文件」的想法是錯誤的?

編輯:我有裝載配置文件沒有問題。我很擔心,將所有這些設置加載到內存中的std :: map <字符串string>後,如何讓其他類的函數訪問這些設置。

編輯2:謝謝大家的意見。我知道我在這裏列出的這些模式是FINE,它們被許多程序使用。我很好奇是否有(某種)模式來處理程序的配置。

+0

我不明白爲什麼配置文件是錯誤的。這是以前完成的。 –

+0

如果您的參數需要動態更改,請將XML解析器與配置文件一起使用。否則,使用define/typedef/static常量的好的'Constants.h完成這項工作 – lucasg

+1

如果你擔心靜態/單例的問題,你可以在文件中讀入一次,然後將它傳遞給需要它的任何東西。 – Xymostech

回答

2

可以說,一個配置文件是單身人士合法使用的。 Singleton模式通常被忽視,因爲Singletons在多線程環境中導致競爭條件問題,並且由於它們是全局訪問的,所以遇到了與全局變量相同的問題。但是,如果你在讀取配置文件時Singleton對象被初始化了一次,並且之後從未改變,我想不出有什麼合法的理由稱之爲「反模式」,而不是某種貨物崇拜的心態。這就是說,當我需要將配置文件作爲對象提供給我的應用程序時,我不使用Singleton。通常我將配置對象傳遞給那些需要它的對象/函數。

+1

你是第二個解決方案意味着通過許多不需要它的層傳播配置。特別是對於他提到的數據類型,配置將在最底層使用。在這種情況下,單身是迄今爲止最好的解決方案。 –

+0

@JamesKanze是對的。如果我傳遞配置對象,它必須經過很多層。 – GuLearn

+0

@CharlesSalvia - 「我想不出一個合理的理由來稱之爲」反模式「[...]」單身人士對我提出的問題是重構/測試。雖然您可以更改設置文件中的_values_,但單例允許您編寫不依賴注入的客戶端代碼,但通過在內部訪問get-​​instance。這會導致深入的,非顯而易見的依賴關係,這種依賴關係會遍佈代碼庫,並且可能很難在以後進行替換。如果你的設置類不是單身人士,你可以保留所有優點,但隱藏的非集中依賴問題除外。 – utnapistim

0

運行時間如果要在運行時讀取配置,可以將它們存儲在.ini文件中,並使用準備好的類庫來解析和讀取它們。然後將它們保存在程序的內存中以有效地訪問它們。

編譯時 這是這樣,你可以使用一個分離的頭文件和存儲配置爲const項目。您可以使用const,extern,enum,...

+0

我得到的印象是,他更感興趣的是,一旦讀入數據(例如全局數據和傳遞數據),而不是如何存儲設置,他對數據的處理方式更感興趣。另外,'.ini'不是一個很好的格式 - 我會推薦XML,除非你因爲遺留原因而堅持使用'.ini'。使用XML不一定比'.ini'複雜。使用類似'Boost.PropertyTree'的東西,它避免了一些限制。 – JBentley

+1

@JBentley XML很複雜,既可以讀取也可以寫入。如果您仍然需要XML解析器,並且您可以使用理解XML的工具來管理配置工具,那就是要走的路。否則......對於很多應用程序來說,'.ini'格式是一個適度的妥協。對於更多,你可以使它更簡單;例如沒有部分。 –

+1

@JamesKanze通過'Boost.PropertyTree',你甚至不需要意識到底層格式是XML,因爲數據的讀寫是完全封裝的(事實上,你甚至可以在XML和.ini之間進行平凡的切換,而無需修改你的與數據交互的代碼)。 – JBentley

1

我知道解決這個問題的最好模式是通過一個選項類,它在創建/配置時被注入到您的代碼中。

步驟:

  1. 創建選項解析類
  2. 配置什麼參數,它應該接受的選項,它們的默認值(默認值可以是你「最可能的」默認值)
  3. 解析器
  4. 寫客戶端代碼接受選項作爲參數(而不是單身和/或靜態的東西)。
  5. 創建對象時注入選項。

看看boost.program_options爲已經成熟的模塊程序選項。 如果您熟悉python,請查看examples in the doc of argparse(相同的概念,在python庫中實現)。他們很容易從中獲得概念和交互。

相關問題