• <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, 評(píng)論 - 12, 引用 - 0
            數(shù)據(jù)加載中……

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

             

                     單件模式是一種較為簡(jiǎn)單的創(chuàng)建型模式,在日常的開(kāi)發(fā)中也常常使用。目的是在應(yīng)用程序中保證某個(gè)類(lèi)的對(duì)象僅能有一個(gè)。在C++的世界中,因?yàn)樗皇羌兠嫦驅(qū)ο蟮恼Z(yǔ)言,它支持全局變量的特性,所以在許多的場(chǎng)合它可以用全局變量來(lái)替代。非常典型的例子就是在MFC的應(yīng)用程序中的theAPP對(duì)象,它就是一個(gè)全局的唯一對(duì)象。類(lèi)似這樣的例子在C++的程序中有許多,在C++中存在這樣的現(xiàn)象是有一定的原因。這里先介紹一個(gè)基于C++實(shí)現(xiàn)的單件模式例子。

             1#pragma once
             2#include <deque>
             3
             4//////////////////////////////////////////////////////////////////////////
             5// Forward declaration
             6//
             7//
             8//////////////////////////////////////////////////////////////////////////
             9class CSendJob;
            10class JobDeque;
            11
            12/// <summary>
            13/// 本類(lèi)為作業(yè)啟動(dòng)信息儲(chǔ)存體
            14/// 此類(lèi)僅為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    /// 可以并行執(zhí)行的作業(yè)數(shù)目
            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/// 這里僅對(duì)全局唯一的作業(yè)對(duì)象地址作比較
             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// 靜態(tài)變量
             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 進(jìn)入互斥區(qū)成功
            118        {
            119            if(NULL == m_spJobDeque)
            120            {
            121                m_spJobDeque = new JobDeque();
            122            }
                                 退出斥區(qū)

            123        }

            132    }

            133    return m_spJobDeque;
            134}

            135
            136void JobDeque::DestroyJobDeque()
            137
            138    if(m_spJobDeque)
            139    {進(jìn)入互斥區(qū)

            140        delete m_spJobDeque;
            141        m_spJobDeque = 0;
                             退出互斥區(qū)
            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

             

                     在這里就省略全局實(shí)例的的例子,在上面的例子中不僅有取得實(shí)例的靜態(tài)函數(shù),還有銷(xiāo)毀實(shí)例的靜態(tài)函數(shù)。客戶可以任何地方及任何時(shí)間調(diào)用獲得單件的函數(shù),但是用戶只能且必須在應(yīng)用程序的最后出口處調(diào)用釋放實(shí)例的函數(shù)。也曾看過(guò)C++實(shí)現(xiàn)的單件模式的例子,例子中沒(méi)有銷(xiāo)毀函數(shù)。這與C#JAVA這樣的純面向?qū)ο髮?shí)現(xiàn)的例子非常地相似。可是C++中并沒(méi)有自動(dòng)垃圾回收裝置,所以還是要我們自己在某個(gè)地方銷(xiāo)毀new出來(lái)的這個(gè)全局實(shí)例對(duì)象。在上面可以看出C++實(shí)現(xiàn)的單件模式不及全局變量來(lái)得簡(jiǎn)單而高效。我持有這個(gè)觀點(diǎn)是基于以下兩個(gè)方面的考慮

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

            (2)    利用全局變量的方案產(chǎn)生的實(shí)例對(duì)象會(huì)在程序退出時(shí)自動(dòng)地銷(xiāo)毀對(duì)象,而單件模式需明確地delete實(shí)例。

            這里并沒(méi)有斷言全局變量就優(yōu)于單件模式,出于如下的考慮可能又會(huì)選用單件模式

            (1)    全局變量的方式使代碼的耦合度提高了,而且需事先總體設(shè)計(jì)好。須保證開(kāi)發(fā)人員和后續(xù)的維護(hù)人員不能再去產(chǎn)生的新的實(shí)例,theApp全局實(shí)例是MFC世界基礎(chǔ)的知識(shí)了。

            (2)    單件實(shí)例的構(gòu)造函數(shù)的參數(shù)中需要自定義對(duì)象實(shí)例時(shí)也會(huì)迫使開(kāi)發(fā)人員選用單件模式。

             

                  我認(rèn)為兩種方案都有優(yōu)點(diǎn)和缺點(diǎn),不能說(shuō)一個(gè)方案絕對(duì)地優(yōu)于另外一個(gè)方案。究竟選用哪種方案取決于應(yīng)用的環(huán)境的約束以及開(kāi)發(fā)人員的偏好。這里闡述了一些個(gè)人的觀點(diǎn),希望能起到拋磚引玉的作用。

            posted on 2009-07-14 17:11 Robertxiao 閱讀(1166) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): C++

            亚洲国产另类久久久精品小说| 久久久青草青青国产亚洲免观| 中文字幕日本人妻久久久免费| 久久精品久久久久观看99水蜜桃| 亚洲精品乱码久久久久久蜜桃不卡 | 久久久久人妻一区精品| 人妻无码精品久久亚瑟影视| 99久久亚洲综合精品网站| 99久久精品日本一区二区免费| 久久久久免费视频| 久久久久亚洲精品天堂| 99久久精品费精品国产| 国产精品久久久久久久久软件| 精品多毛少妇人妻AV免费久久| 久久99精品久久久久久| 2021国产精品久久精品| 久久久青草久久久青草| 久久人人爽人人爽人人片AV高清| 国产高潮国产高潮久久久| 久久国产精品无码网站| 国产精品久久久久久影院 | 久久强奷乱码老熟女| 久久露脸国产精品| 国产精品久久久久天天影视| 久久人人爽人人爽AV片| 青青热久久综合网伊人| 狠狠色狠狠色综合久久| 久久久久久无码国产精品中文字幕 | 久久精品无码一区二区日韩AV | 亚洲AV日韩AV天堂久久| 蜜臀久久99精品久久久久久| 亚洲国产天堂久久综合| 久久精品国内一区二区三区| 亚洲精品乱码久久久久久蜜桃不卡| 久久精品国产亚洲7777| 青青草原1769久久免费播放| 日日狠狠久久偷偷色综合0| 国产精品美女久久久久av爽| 伊人热人久久中文字幕| 亚洲精品高清国产一久久| 国产成人精品免费久久久久|