這不完全是一個答案,只是評論時間太長了其他評論的反應,這是有關這個問題。
請不要使用Singleton。您陳述的理由是您將使用它來存儲配置信息,並且該配置信息需要在程序中的任何地方訪問。
這是一個全局變量的原因(雖然,恕我直言,不一定一個偉大的),但不是一個Singleton的理由。存在配置的多個對象有什麼危害?如果所有用戶使用全局變量來訪問它們,它們將全部使用同一個變量。爲什麼將實例的數量強制限制爲1會有幫助?
其次,在未來會發生什麼,當你需要臨時增加一些配置選項?不知道怎麼說,你的程序需要將自己作爲一個子程序或者稍微不同的配置信息來運行,然後恢復原來的配置?或者,也許你需要用幾種不同的方式來測試配置,然後將其恢復到原始狀態?有了Singleton和一個全局變量,這變得非常棘手。但是如果你使用了更靈活的東西,那很簡單。我個人認爲,將配置選項以明確的方式傳遞給所有需要它們的東西並不一定是一種不好的方式。但如果你認爲這是無法忍受的,這裏是一個另類:
template <typename T>
class DynamicallyScoped {
public:
explicit DynamicallyScoped(T &stackinstance) : oldinstance_(0) {
oldinstance_ = S_curinstance;
S_curinstance = &stackinstance;
}
~DynamicallyScoped() {
S_curinstance = oldinstance_;
oldinstance_ = 0;
}
static T *curInstance() { return S_curinstance; }
private:
static T *S_curinstance;
T *oldinstance_;
// Made private and left undefined on purpose.
DynamicallyScoped(const DynamicallyScoped &b);
const DynamicallyScoped &operator =(const DynamicallyScoped &b);
};
這使您可以替換當前實例的範圍,當範圍消失,系統將自動恢復。它還允許你在你的程序中的任何地方說DynamicallyScoped<Foo>::curInstance()->get_something();
,除了靜態或全局對象的構造函數,並期望獲得一些有用的東西。
這是一個塗鴉,可能在這種形式中很有用。但我可以想象它可能更好的方式。例如,通過一些修改,您可以擁有幾個相同類型的動態範圍變量。
用法示例:
#include <iostream>
template <>
int *DynamicallyScoped<int>::S_curinstance = 0;
extern void doSomething();
extern void doSomethingElse();
extern void printTheInt();
int main(int argc, char *argv[])
{
int x = 5;
DynamicallyScoped<int> theInt(x);
printTheInt();
doSomething();
doSomethingElse();
}
void doSomething()
{
printTheInt();
}
void doSomethingElse()
{
int newint = 6;
DynamicallyScoped<int> subint(newint);
doSomething();
}
void printTheInt()
{
::std::cout << "_The_ integer's value is: "
<< *DynamicallyScoped<int>::curInstance() << '\n';
}
至於那可以創造你的「全局配置文件」對象的多個實例的煩惱,不硬編碼的文件名。將main
中的對象構造爲堆棧變量,並將其作爲參數賦予文件名。如果代碼的其他部分創建了配置文件對象的實例,除非它們也提供了全局配置文件的名稱,否則沒有問題。如果他們這樣做,他們應該得到他們得到的。
爲什麼在`static`關鍵字前面有`-`? – 2011-01-26 18:31:15
對不起,我從emacs粘貼它,其中一個小模式以這種方式格式化源代碼。編輯。 – 2011-01-26 18:32:53
很明顯,這表明vi是優越的;-) – 2011-01-26 18:46:48