[英]Init values by using (somewhat) global variables vs. static function variables?
我在整個代碼中都需要一些小輔助函數。 要工作,需要使用一些數據進行初始化。 我應該在哪里存儲init數據?
我想出了兩種方法:
我在helper.cpp文件的范圍內創建靜態變量,我使用專用的setter函數設置它,然后在我的幫助函數中使用。
static int _initData = 0;
void initHelpMe(int initData)
{
_initData = initData;
}
void helpMe()
{
doSomethingWith(_initData);
}
或者我在原始輔助函數中使用靜態函數變量,並使用默認參數。
void helpMe(int initData = 0)
{
static int _initData = 0;
if (initData != 0)
_initData = initData;
doSomethingWith(_initData);
}
(假設0在initData的有效數據范圍之外,並且我沒有顯示額外的代碼,以確保首次調用該函數時引發錯誤而不首先啟動它。)
這兩種方法有哪些優點/缺點,是否有更好的方法呢?
我當然喜歡第二種方法,因為它將所有功能保存在一個地方。 但我已經知道它不是線程安全的(這不是一個問題atm)。
並且,為了使這更有趣,盡管是C ++,但這不是用於面向對象而是用於過程代碼。 所以請不要提出建議對象或類的答案。 想象一下,它是C語言的C語言。
我打算建議你將數據包裝到一個對象中,直到我意識到你要求一個帶有C ++標簽的C解決方案......
您的兩種解決方案都有其優點。
第二個是我更喜歡的,假設我們只是“看起來像什么/可維護性”。 但是,如果使用initData == 0
多次調用helpMe
,則存在一個缺點,因為在第一種情況下不存在額外的if
。 如果doSomethingWith()
足夠長的函數和/或編譯器能夠內聯helpMe
(並且initData
是常量),這可能是也可能不是問題。
當然,代碼中的某些東西也必須調用initHelpMe
,所以無論如何它可能會變成相同的。
總結:首選基於隔離/封裝的第二個。
我顯然更喜歡第二個! 不同編譯單元中的全局靜態數據以未指定的順序初始化(盡管在一個單元中)。 首次調用時初始化函數的本地靜態數據。
示例 :
如果你有兩個轉換單元A和B.單元A在初始化期間調用單元B的函數helpMe。假設初始化的順序是A,B。第一個解決方案將零初始化_initData設置為某個initData。 之后,單元B的初始化將_initData重置為零,並可能產生內存泄漏或其他危害。
還有第三種解決方案:
void helpMe(int initData = 0)
{
static std::once_flag once;
static int _initData = 0;
std::call_once(once, [&] {
_initData = initData;
}
doSomethingWith(_initData);
}
我有兩種感覺。
首選隔離選項2,但選項1適合移植到C ++類。 我已經編碼了兩種方式。 它歸結為SW架構。
讓我提出另一點。
兩個選項都在下方:您沒有將初始化限制為一次。 “需要用一些數據進行初始化”。 OP的條件似乎確保initHelpMe(123)
或HelpMe(123)
的正確初始化,然后是helpMe()
,但不要阻止/檢測二次初始化。
如果需要防止/檢測到輔助,則可以使用一些附加代碼。
// Initialization
if (_initData != 0) {
; // Handle error
}
_initData = initData;
我使用的另一種范例如下。 它可能無法在您的代碼中實現,因為它不會將initData
作為參數傳遞,但神奇地可以獲得它。
void helpMe(void) {
static int Initialized = 0;
if (!Initialized) {
Initialized = 1;
_initData = initData();
}
doSomethingWith(_initData);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.