2010-06-05 78 views
1

這是我關於堆棧溢出的第一個問題,所以要溫和。在C++中實現C#「只讀」行爲

讓我先解釋我想看到的確切行爲。如果你熟悉C#,那麼你知道將變量聲明爲「只讀」允許程序員爲該變量賦值一次。進一步嘗試修改該變量將導致錯誤。

我在做什麼之後:我想確保我定義的任何和所有單級類都可以在我的程序中準確實例化一次(更多細節在底部)。

我要實現我的目標的方法是使用的extern聲明一個全局參考單噸(我將在同一時間我選擇以後實例。我有幾分像這樣,

namespace Global 
{ 
    extern Singleton& mainInstance; // not defined yet, but it will be later! 
} 

int main() 
{ 
    // now that the program has started, go ahead and create the singleton object 
    Singleton& Global::mainInstance = Singleton::GetInstance(); // invalid use of qualified name 
    Global::mainInstance = Singleton::GetInstance(); // doesn't work either :( 
} 

class Singleton 
{ 
    /* Some details ommited */ 

    public: 
     Singleton& GetInstance() 
     { 
      static Singleton instance; // exists once for the whole program 
      return instance; 
     } 
} 

但是這並沒有真正的工作,我不知道從哪裏何去何從

一些細節什麼我起來反對:

我很擔心線程作爲我的工作代碼將處理遊戲邏輯,而 與我將創建的幾個第三方流程和其他流程進行通信。最終我會有 實現某種同步,以便多個線程可以訪問Singleton類中的信息 ,而不用擔心。因爲我不知道我可能喜歡做什麼樣的優化,或者究竟是什麼線程需要(從來沒有做過一個真正的項目使用它),我認爲 能夠預測控制何時實例化單例將是一個好事情。

想象一下,如果進程A創建進程B,其中B包含針對多個文件和/或庫分發的多個單一進程。如果我不能可靠地確保這些單例對象實例化的順序(因爲它們可以相互依賴,並且在NULL對象上調用方法通常是一件壞事),這可能是一場真正的噩夢。

如果我在C#中,我只是使用readonly關鍵字,但有什麼辦法可以在C++中實現這個 (編譯器支持)行爲?這是個好主意嗎?感謝您的任何反饋。


編輯

如果我被鎖定在以下上面的代碼示例中,選擇的答案是做什麼,我需要最簡單的方法。儘管我只打算創建其中一個EntryPoint對象,但我決定從單例模式中改變模式。

class EntryPoint 
{ 

    /* Intentionally defined this way to discourage creation */ 
    EntryPoint(const EntryPoint &); // undefined & private 
    EntryPoint& operator=(const EntryPoint &); // undefined & private 

    // public 
    EntryPoint() 
    { 
     /* All of the action is performed here! */ 
    } 

    /* Other supporting functions */ 
} 

// The easier to understand main function! 
int main() 
{ 
    EntryPoint * ep = new EntryPoint(); // transfer control to the entrypoint 
    delete ep; 
} 

有一個問題我想我需要所有這些單身的原因是我計劃建立一個能夠支持模塊化插件式應用的大架構。我也想要更多的錯誤檢查和內存保護,以儘量減少內存泄漏。我很高興地發現跨平臺的Qt(http://qt.nokia.com/)提供了一個守護指針和其他很酷的功能。

+3

聽起來像'const'應該這樣做。但是,不,我認爲這不是一個好主意。單身人士在他們「正常」的化身中已經夠糟糕了。讓他們變得更加複雜只會回來並咬你。爲什麼你有這些單身人士?控制實例化順序的最簡單方法是停止生成一半變量static/globals/singletons – jalf 2010-06-05 12:26:32

回答

1

爲什麼不直接使用Singleton::GetInstance?爲什麼你需要將其存儲在(只讀)全局?這也解決了依賴性問題。

+0

+1這也是我將如何調用Singleton GetInstance方法。 – 2010-06-05 12:02:21

+0

我的一半想知道是否有可能。但是我想要做的是從訪問中分離實例化。我的感覺是,有一天我可能會創建一個AccessManager類,它負責使用緩存技術或更復雜的東西來加速對全局數據的訪問(可能需要查詢數據庫,誰知道)。 現在它不那麼糟糕,因爲它很簡單,但我不想處於難以優化的情況,因爲我在整個代碼庫中都有很多對Singleton :: GetInstance()的調用。 – 2010-06-05 12:07:03

+0

你可以用'GetGraphicsEngine'和'GetInputEngine'等靜態方法創建一個類(或幾個類),現在調用'Singleton :: GetInstance'? – strager 2010-06-05 12:22:54

1

只允許訪問通過調用:

Singleton::GetInstance 

通過使您的副本和任務的構造私人

private: 
    Singleton(){} 
    Singleton(Singleton const&){}; //copy ctor private 
    Singleton& operator=(Singleton const&){}; 
+0

和Singleton :: GetInstance是靜態的 – Joshua 2010-06-06 00:01:48

0

試想一下,如果進程A創建了進程B,其中B包含幾個單身

執行本

你以爲你需要所有這些單身?你知道Anti Singleton Movement嗎? ;-)

+0

有趣的視頻:) – 2010-06-05 14:51:51

+0

@Matt:「有趣」,你的意思是「有趣」還是「可笑」? – fredoverflow 2010-06-05 15:06:06

+0

這兩個我猜想:)我只看到了前10分鐘,雖然我同意全球狀態應該避免(我們不知道這一切?),我也從經驗知道,它存在:它被稱爲外部世界(數據庫,其他應用程序...)。儘管如此,我仍然很高興。祝賀4k達成:) – 2010-06-05 16:27:08