• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            SmartPtr
            本博客已搬至:http://www.cnblogs.com/baiyanhuang/
            posts - 29,comments - 176,trackbacks - 0

            By SmartPtr(http://www.shnenglu.com/SmartPtr/)

             

            對于單件模式, 我想大家應該都不陌生,它可以說是GOF23個設計模式中最簡單,最常用的一個模式了。但看似簡單的東西卻不一定好用,我就在使用時遇到了一個問題。

            1 一個簡單的Singleton

            #include<iostream>
            class Singleton
            {
            public:
                
            static  Singleton& GetSingleton()
                {
                    
            static Singleton singleton;
                    
            return singleton;
                }
                
            void Print()
                {
                    std::cout
            <<"Singleton Print\n";
                }
            private:
                Singleton::Singleton()
                {
                    std::cout
            <<"singleton constructor\n";
                }
            };

            這個類提供了一些的功能(函數Print), 并禁止我們創建這個類的對象(構造函數為private), 提供給我們一個靜態函數接口來訪問這個單件對象(GetSingleton),利用靜態變量的特點實現了其單一性。但是, 這個類有問題嗎?
            2 問題所在
            是的,上面這個簡單的類的確存在問題,而且是一個很嚴重的問題,這個問題讓Singleton類完全失去它存在的意義, 因為它不再唯一!
            是的, 當我們只在一個模塊中使用這個類時(比如說,一個exe),這個類是沒有問題的。但是, 一個稍微復雜一點的軟件, 為了開發的便捷,提高復用度,降低耦合性等原因,其難免會被分成好幾個模塊。那么假設講我現在有兩個模塊,一個DLL(singleton.dll), 用來提供一些基礎的功能, 一個EXE(test.exe),用來提供真正的軟件邏輯。 我現在singleton.dll中封裝了一個Print的函數間(用類Singleton實現)并暴露出來。

            singleton.dll

            void Print()
            {
                Singleton::GetSingleton().Print();
            }

            并在test.exe中這樣調用:
            Test.exe

            Singleton::GetSingleton().Print();
            Print();

            這個時候,我們會發現在調用Singleton::GetSingleton().Print()時會產生一個Singleton對象, 而在調用Print()時, 也會產生一個Singleton對象, 也就是說我們有了兩個Singleton實例, singleton不再是singleton。那么,為什么會這樣呢。
            static  Singleton& GetSingleton()
            {
                static Singleton singleton;
                return singleton;
            }

            這個函數應該只會在第一次調用時創建Singleton對象,無論如何, 不應該出現會創建兩次, 調用兩次構造函數的情況。對于靜態變量特性理解沒錯(只在第一次經過時被初始化), 編譯器也沒問題(vc8.0),難道兩次經過該靜態變量是都是第一次? 那么,難道兩次調用的GetSingleton函數并不是同一個函數?讓我們逐一來看:

            1) Singleton::GetSingleton().Print()
            在Test.exe中直接調用該函數,因為包含的頭文件singleton.h有完整的實現, 在鏈接時會在Test.exe保存一份Singleton::GetSingleton()的實現代碼。
            將其標為Singleton::GetSingleton_1();
            2) Print();
            Print()函數是從singleton.dll中導出而來的,而Print()會調用Singleton::GetSingleton(), 在鏈接模塊singleton.dll時,因為其包含的頭文件有完整的實現, 這個DLL也會保存一份Singleton::GetSingleton()的執行代碼。 我將它標為Singleton::GetSingleton_2(), 雖然我們包含的是同一個頭文件,兩個是相同的函數名字, 但是這個函數在兩個不同的模塊中都存有一份獨立的實現。實際上, 他們已經成為兩個不同的函數了。

            看來,兩個函數的確不是同一個函數。

            3 如何解決

            既然知道了原因,就會有相應的解決方法。既然我們知道有兩份獨立的代碼分別存在于兩個模塊中, 那么我們要做的就是讓它只有一份。最好的結果就是這個函數保存在dll中, 在Test.exe不再存有該函數的執行代碼, 而是調用dll中的那個函數。現在結果很明顯了:將Singleton.h編譯鏈接singleton.dll并將外部需要使用的函數暴露出來。這樣,不管有多少模塊使用到singleton, 我們始終執行singleton.dll中的代碼。

            如下:
            SINGLETON_API static Singleton& GetSingleton()
            {
                 static Singleton singleton;
                 return singleton;
            }
            注:
            #ifdef SINGLETON_EXPORTS
            #define SINGLETON_API __declspec(dllexport)
            #else
            #define SINGLETON_API __declspec(dllimport)
            #endif
            這樣在test.exe中使用該函數時,就不會再產生一個副本了,從而保證了我們的應用程序只有一個singleton實例

            posted on 2007-08-28 11:37 SmartPtr 閱讀(1519) 評論(0)  編輯 收藏 引用
            成人国内精品久久久久一区| 久久久高清免费视频| 久久久久人妻一区二区三区vr| 一本一本久久a久久综合精品蜜桃 一本一道久久综合狠狠老 | 久久国产亚洲精品无码| 久久99精品国产麻豆| 久久97久久97精品免视看秋霞 | 久久精品九九亚洲精品天堂| 麻豆精品久久精品色综合| 午夜视频久久久久一区| 99久久er这里只有精品18| 精品久久久久久无码国产| 久久香综合精品久久伊人| 精品久久人人爽天天玩人人妻| 亚洲欧洲中文日韩久久AV乱码| 性做久久久久久久| 国产精品亚洲美女久久久| 久久精品国产清高在天天线| 久久久91人妻无码精品蜜桃HD| 久久AV高清无码| 久久精品一区二区影院| 久久久91精品国产一区二区三区| 中文字幕日本人妻久久久免费 | 97精品国产97久久久久久免费| 欧美成人免费观看久久| 久久综合综合久久97色| 久久久久亚洲AV成人片| 亚洲中文精品久久久久久不卡| 伊人久久亚洲综合影院| 久久99精品久久久久久噜噜| 久久伊人精品青青草原高清| 国产精品久久久香蕉| 中文精品久久久久人妻| 合区精品久久久中文字幕一区 | 久久久久久A亚洲欧洲AV冫| 日日噜噜夜夜狠狠久久丁香五月| 伊人久久精品影院| 欧美无乱码久久久免费午夜一区二区三区中文字幕 | 精品综合久久久久久97| 久久精品综合网| 亚洲国产小视频精品久久久三级|