4/28/2010

Singleton Pattern

Singleton Pattern帶來的是保證一個class只有一個實體,無法產生第二個第三個... 使用這種模式的概念是系統中永遠只會唯一存在,如OS kernal、program core或hardward controller等。C++實作如下:
class IOController {
private:
    IOController() { /*implement*/ }
    IOController(const Core&);
    IOController& operator=(const IOController&);
    virtual ~IOController();

public:
    static IOController& getIOController() {
        static IOController IOController;
        return IOController;
    }

    void memberFunctionA() {}
    void memberFunctionA() {}

private:
    MemberData A;
    MemberData B;
};
一個正確的Singleton應該確保唯一性,C++確保唯一的保護措施有三點:
1. default constructor宣告為private並實作(空內容也沒關係)。因此實體只能在內部產生,外部無法取得建構子。
2. copy constructor and operator=宣告為private並不實作。宣告為private使得外部無法取得函式原型,不實作它是因為不需要,並且令編譯失敗(若使用到copy constructor or operator=,因為沒有實作,會產生連結錯誤,確保不能複製物件)
3. destructor宣告為private,防止外部刪除實體。(這一點可商議。若getIOController()回傳IOController*,則destructor必須宣告為private;若getIOController回傳IOController&,那這點可忽略)

另外值得注意的是getIOController()中宣告static IOController IOController物件,這樣寫法是依賴編譯器的一個規則,"函式內的靜態物件在該函式第一次執行時被初始化",所以getIOController從末被呼叫時,IOController沒有被初始化,效能並沒有降低。

提到唯一性一定會想起靜態函式和靜態物件,那Singleton可以利用靜態來實作嗎
class IOController {
public:
    static void memberFunctionA() {}
    static void memberFunctionA() {}
    // ...

private:
    static MemberData A;
    static MemberData B;
    // ...
};
這樣看似沒甚麼問題,也不需要宣告private之類有的沒的。但是這情況下會缺乏擴充性,假如現在需要第二代IOController2,且保留IOController,視不同情況選擇使用。這樣實作IOController2會很困難,因為靜態函式不能成為虛擬函式,所以IOController和IOController2不能使用多型。若以原來的範例則可以輕鬆解決。
class IOController2 : public IOController {
private:
    IOController2() { /*implement*/ }
    IOController2(const IOController2&);
    IOController2& operator=(const IOController2&);
    virtual ~IOController2();

public:
    static IOController2& getIOController2() {
        static IOController2 IOController2;
        return IOController2;
    }

    void memberFunctionA() {}
    void memberFunctionB() {}

private:
    MemberData C;
    MemberData D;
};
void main {
    bool condition = true;
    Core& core = condition? IOController2::getIOController2(): IOController::getIOController();

    core.memberFunctionA();
    core.memberFunctionB();
}

1 則留言:

Golden Flower 提到...

Nice Site very useful information a explanation in English would reach out to the global audience though regular users can use the translators but first impression for other language users would not take them forward. Thanks for sharing for some Inspirational stories visit. HTTP://MALENADUGROUP.BLOGSPOT.IN/