我需要確保程序執行過程中始終存在某個類的至少一個實例。單身人士不會這樣做,因爲(除其他原因)我可能在將來需要更多的實例。一個靜態類也可以做,但感覺就像走向全球......我也想要一些私人成員,包括函數和變量。如何確保至少有一個類的實例?
我想過讓shared_ptr保持安全的地方,但這似乎是一個粗糙的黑客。
有沒有做到這一點的標準方式?
編輯
澄清:這不是能夠檢查一個實例是否仍然存在的問題。任何時候都必須存在的實例。原因是類中有靜態成員變量,它們應保持其狀態。
我需要確保程序執行過程中始終存在某個類的至少一個實例。單身人士不會這樣做,因爲(除其他原因)我可能在將來需要更多的實例。一個靜態類也可以做,但感覺就像走向全球......我也想要一些私人成員,包括函數和變量。如何確保至少有一個類的實例?
我想過讓shared_ptr保持安全的地方,但這似乎是一個粗糙的黑客。
有沒有做到這一點的標準方式?
編輯
澄清:這不是能夠檢查一個實例是否仍然存在的問題。任何時候都必須存在的實例。原因是類中有靜態成員變量,它們應保持其狀態。
I need to ensure that there is at all times during programm execution at least one instance of a certain class.
所以我想解決方案從決定誰負責存儲它開始。您可以:將其內部存儲在類中(靜態)或將其返回給調用者/客戶端上下文(並依賴於客戶端上下文來保留它)。既然你說「單身不會做」的解決方案應該是這樣的:
class TheClass
{
public:
// this doesn't have to be a std::shared_ptr<WithContext>
// and probably shouldn't be (see below)
typedef <implementation-defined> GlobalContext;
GlobalContext InitContext(); // return instance
};
void main(/* ... */)
{
// do this before any code that uses TheClass instances
auto global_execution_context = TheClass::InitContext();
// rest of your application code goes here
}
I thought about keeping a shared_ptr somewhere safe, but that seems to be a rough hack.
你看到了什麼,因爲它的缺點?如果因爲它是一個模糊的依賴項,你可以爲它添加一個測試,或者當上下文被刪除/影響/不存在時拋出異常。你也可以在TheClass的構造函數中要求引用你的上下文。
你不應該有GlobalContext中是一個std :: shared_ptr的,但它自己類型的原因是,這是你的要求,實際上等同於:
你需要一個(新)類型的對象,保持共同實例之間的TheClass狀態。
我總是實現這個使用內部靜態計數器,它在構造函數中遞增並在析構函數中遞減。
是的,肯定你檢查'至少有一個實例'的方法應該是靜態的。
UPDATE:OK,我看到這裏的答案錯誤,所以我張貼我的答案:
class Test
{
private:
static int m_count;
public:
Test() { ++m_count; }
Test(const Test&) { ++m_count; }
~Test()
{
--m_count;
}
static bool hasInstance()
{
return (m_count > 0);
}
};
int Test::m_count = 0;
int main()
{
return 0;
}
使用靜態成員,並將其設置在構造函數/析構函數:
class Test
{
static int i;
public:
Test()
{
i++;
}
Test(const Test &t) // It's suspicious
{
i++;
}
~Test()
{
i--;
}
static bool hasInstance()
{
return i>0;
}
};
static int Test::i = 0;
然後,你就知道如果Test
有任何實例或沒有。
請將'static'修飾符添加到hasInstance()。這樣你的答案就是我的方法100%的例證。 –
順便說一下錯誤:m_hasInstance不應該在析構函數中重置!計數器的解決方案可能更好。 –
你也需要在複製構造函數中增加(或防止複製)。 –
一種工廠類如何包含所有實例的集合?
喜歡的東西:
template<typename T>
class least_one_factory
{
static std::vector<T> instances_;
public:
least_one_factory()
{
// Make sure there is an instance of `T` in our collection
instance_.push_back(T());
}
T& get()
{
return instances_.front();
}
T& get(int n)
{
return instances_.at(n);
}
T& create()
{
instances_.push_back(T());
return instances_.back();
}
int count() const
{
return instances_.size();
}
operator T&()
{
return get();
}
};
template<typename T>
std::vector<T> least_one_factory<T>::instances_;
現在你可以這樣做:
struct some_class {};
least_one_factory<some_class> some_class_factory;
變量some_class_factory
包含至少的some_class
一個實例。你可以用some_class_factory.get()
得到它。如果some_class_factory
是全局變量,則在調用main
之前加載程序時將創建some_class
的實例。
這是更多(但不完全)我想要的;)如果可能的話,我想讓這個代碼的其餘部分透明,而不必編寫'.get()' – steffen
@steffen添加了轉換運算符,現在它可以用作'some_class var = some_class_factory;'轉換運算符只返回第一個實例。儘管如此,很難讓它更「透明」,尤其是創建它們。 –
爲什麼你至少需要某個類的至少一個實例? –
你將如何訪問這個實例?它可以被構造成懶惰嗎? –
@DanF:爲了不鬆動一些靜態成員變量的狀態。 – steffen