• <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>
            隨筆 - 64, 文章 - 11, 評論 - 12, 引用 - 0
            數據加載中……

            在C++中單件模式與全局實例兩種方案的比較

             

                     單件模式是一種較為簡單的創建型模式,在日常的開發中也常常使用。目的是在應用程序中保證某個類的對象僅能有一個。在C++的世界中,因為它不是純面向對象的語言,它支持全局變量的特性,所以在許多的場合它可以用全局變量來替代。非常典型的例子就是在MFC的應用程序中的theAPP對象,它就是一個全局的唯一對象。類似這樣的例子在C++的程序中有許多,在C++中存在這樣的現象是有一定的原因。這里先介紹一個基于C++實現的單件模式例子。

             1#pragma once
             2#include <deque>
             3
             4//////////////////////////////////////////////////////////////////////////
             5// Forward declaration
             6//
             7//
             8//////////////////////////////////////////////////////////////////////////
             9class CSendJob;
            10class JobDeque;
            11
            12/// <summary>
            13/// 本類為作業啟動信息儲存體
            14/// 此類僅為JobDeque所使用,不宜讓其它客戶使用
            15/// </summary>

            16class JobStartInformation
            17{
            18    friend class JobDeque;
            19public:
            20    ~JobStartInformation()
            21    {
            22        //Don`t delete the m_pJob pointer.
            23    }

            24
            25private:
            26    JobStartInformation(CSendJob *pJob, BOOL bManual)
            27        :m_pJob(pJob),
            28        m_bManualStart(bManual)
            29    {
            30    }

            31
            32public:
            33    CSendJob* GetJob() const return m_pJob; }
            34    BOOL IsManualStart() const return m_bManualStart; }
            35
            36private:
            37    BOOL m_bManualStart;
            38    CSendJob *m_pJob;
            39}
            ;
            40
            41class JobDeque
            42{
            43    // Constructor and Destructor
            44public:
            45private:
            46    virtual ~JobDeque(void);
            47private:
            48    JobDeque(void);
            49    JobDeque(const JobDeque &);
            50    JobDeque& operator=(const JobDeque& );
            51
            52    // Methods:
            53public:
            54    void Start( CSendJob *pJob, BOOL bManualStart);
            55    void Completed( CSendJob* pJob);
            56private:
            57    void Launch(); 
            58private:
            59    USHORT m_usRunAmount;
            60    std::deque<JobStartInformation > m_jobDeque;
            61    
            62public:
            63    static JobDeque* GetJobDeque();
            64    static void DestroyJobDeque();
            65
            66private:
            67    ///<summary>
            68    /// 可以并行執行的作業數目
            69    ///</summary>

            70    static const USHORT m_susParallelAmount;
            71    static JobDeque *m_spJobDeque;
            72
            73#ifdef _DEBUG
            74    void Validate();
            75#else
            76    void Validate()
            77    {
            78    }

            79#endif
            80}
            ;
            81

              1#include "StdAfx.h"
              2#include <algorithm>
              3#include "SendJob.h"
              4#include "JobDeque.h"
              5using namespace std;
              6
              7// JobDeque.cpp
              8///<summary>
              9/// 這里僅對全局唯一的作業對象地址作比較
             10///</summary>

             11bool operator==(const JobStartInformation& lo, const JobStartInformation& ro) throw()
             12{
             13    if(&lo == &ro)
             14    {
             15        return true;
             16    }

             17
             18    if(NULL ==lo.GetJob() && NULL == ro.GetJob())
             19    {
             20        return true;
             21    }

             22    if(NULL == lo.GetJob() || NULL == ro.GetJob())
             23    {
             24        return false;
             25    }

             26    return lo.GetJob() == ro.GetJob();
             27}

             28
             29bool operator!=(const JobStartInformation& lo, const JobStartInformation& ro) throw()
             30{
             31    return !(lo == ro);
             32}

             33
             34bool operator<(const JobStartInformation& lo, const JobStartInformation& ro) throw()
             35{
             36    if(lo == ro)
             37    {
             38        return true;
             39    }

             40    return lo.GetJob() < ro.GetJob();
             41}

             42
             43
             44//////////////////////////////////////////////////////////////////////////
             45// 靜態變量
             46const USHORT JobDeque::m_susParallelAmount =  1;
             47JobDeque* JobDeque::m_spJobDeque = NULL;
             48
             49//////////////////////////////////////////////////////////////////////////
             50// Constructor and Destructor
             51//
             52//
             53//
             54//////////////////////////////////////////////////////////////////////////
             55JobDeque::JobDeque(void)
             56{
             57    m_usRunAmount = 0;
             58}

             59
             60JobDeque::~JobDeque(void)
             61{
             62}

             63
             64//////////////////////////////////////////////////////////////////////////
             65//
             66//
             67//
             68//////////////////////////////////////////////////////////////////////////
             69void JobDeque::Start( CSendJob *pJob, BOOL bManualStart)
             70{
             71    ATLASSERT(pJob && _T("Argument of pJob is NULL in JobDeque::Start."));
             72    if(!pJob)
             73    {
             74        return;
             75    }

             76
             77    JobStartInformation jobInfo(pJob, bManualStart);
             78    deque<JobStartInformation >::iterator itFinder = find(m_jobDeque.begin(), m_jobDeque.end(), jobInfo);    
             79    if(itFinder == m_jobDeque.end())
             80    {
             81        m_jobDeque.push_back(jobInfo);
             82        pJob->SetSyncState(CSendJob::COPYING);
             83    }

             84    Launch();
             85    return;
             86}

             87
             88void JobDeque::Completed( CSendJob* pJob )
             89{
             90    ATLASSERT(pJob && _T("Argument of pJob is NULL in JobDeque::Start."));
             91    if(!pJob)
             92    {
             93        return;
             94    }

             95    --m_usRunAmount;
             96    Validate();
             97    Launch();
             98    return;
             99}

            100
            101void JobDeque::Launch()
            102{
            103    if(m_usRunAmount < m_susParallelAmount && m_jobDeque.size() > 0)
            104    {
            105        m_jobDeque.front().GetJob()->Send(m_jobDeque.front().IsManualStart());
            106        m_jobDeque.pop_front();
            107        ++m_usRunAmount;
            108        Validate();
            109    }

            110}

            111
            112JobDeque* JobDeque::GetJobDeque()
            113{
            115    if (NULL == m_spJobDeque)
            116    {
            117        if 進入互斥區成功
            118        {
            119            if(NULL == m_spJobDeque)
            120            {
            121                m_spJobDeque = new JobDeque();
            122            }
                                 退出斥區

            123        }

            132    }

            133    return m_spJobDeque;
            134}

            135
            136void JobDeque::DestroyJobDeque()
            137
            138    if(m_spJobDeque)
            139    {進入互斥區

            140        delete m_spJobDeque;
            141        m_spJobDeque = 0;
                             退出互斥區
            142    }
            143}

            144
            145#ifdef _DEBUG
            146void JobDeque::Validate()
            147{
            148    if(m_susParallelAmount < m_usRunAmount || m_usRunAmount < 0)
            149    {
            150        ATLASSERT(_T("The counter in JobDeque work error!"));
            151    }

            152}

            153#endif
            154

             

                     在這里就省略全局實例的的例子,在上面的例子中不僅有取得實例的靜態函數,還有銷毀實例的靜態函數。客戶可以任何地方及任何時間調用獲得單件的函數,但是用戶只能且必須在應用程序的最后出口處調用釋放實例的函數。也曾看過C++實現的單件模式的例子,例子中沒有銷毀函數。這與C#JAVA這樣的純面向對象實現的例子非常地相似。可是C++中并沒有自動垃圾回收裝置,所以還是要我們自己在某個地方銷毀new出來的這個全局實例對象。在上面可以看出C++實現的單件模式不及全局變量來得簡單而高效。我持有這個觀點是基于以下兩個方面的考慮

            (1)    利用全局變量的方案來產生全局唯一實例時不用考慮多線程的情況,在上面的例子中產生實例時考慮了多線程情況。

            (2)    利用全局變量的方案產生的實例對象會在程序退出時自動地銷毀對象,而單件模式需明確地delete實例。

            這里并沒有斷言全局變量就優于單件模式,出于如下的考慮可能又會選用單件模式

            (1)    全局變量的方式使代碼的耦合度提高了,而且需事先總體設計好。須保證開發人員和后續的維護人員不能再去產生的新的實例,theApp全局實例是MFC世界基礎的知識了。

            (2)    單件實例的構造函數的參數中需要自定義對象實例時也會迫使開發人員選用單件模式。

             

                  我認為兩種方案都有優點和缺點,不能說一個方案絕對地優于另外一個方案。究竟選用哪種方案取決于應用的環境的約束以及開發人員的偏好。這里闡述了一些個人的觀點,希望能起到拋磚引玉的作用。

            posted on 2009-07-14 17:11 Robertxiao 閱讀(1150) 評論(0)  編輯 收藏 引用 所屬分類: C++

            久久只有这里有精品4| 97久久精品人人做人人爽| 久久97精品久久久久久久不卡| 亚洲精品国产自在久久| 久久精品国产精品亚洲| 91久久精品国产成人久久| 久久99精品国产一区二区三区 | 亚洲中文字幕无码久久综合网| 亚洲国产成人久久笫一页| 久久se这里只有精品| 久久久99精品一区二区| 久久精品国产黑森林| 亚洲精品国产综合久久一线| 亚洲精品无码久久毛片| 一级女性全黄久久生活片免费| 亚洲欧美日韩久久精品| 久久久亚洲裙底偷窥综合| 人妻精品久久久久中文字幕69| 精品国际久久久久999波多野| 国产精品对白刺激久久久| 久久电影网一区| 一本色综合久久| 久久精品无码午夜福利理论片| 99久久免费国产精精品| 久久久久久久综合综合狠狠| 欧美激情精品久久久久久久九九九 | 久久国产三级无码一区二区| 午夜精品久久久久久久无码| 欧美国产成人久久精品| 久久久久高潮毛片免费全部播放 | 久久婷婷色香五月综合激情 | 亚洲国产高清精品线久久| 亚洲va中文字幕无码久久| …久久精品99久久香蕉国产| 国产精品99久久久久久董美香 | 久久国产影院| 日韩精品久久无码人妻中文字幕 | 久久久久久无码Av成人影院| 国产日韩欧美久久| 欧美丰满熟妇BBB久久久| 久久久久国产一区二区三区|