• <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>

            Error

            C++博客 首頁 新隨筆 聯系 聚合 管理
              217 Posts :: 61 Stories :: 32 Comments :: 0 Trackbacks

            #

            endpoint:描述socket編程體系下的一個端點。一個IP+PORT ?

            port還是一樣的unsigned short

            提供一個data()方法,來返回原生的地址結構體。這是一個好的思路,這樣系統就不會封閉了。

             

            address: 抽象的一個IP地址,可以是ipv4、ipv6。對外接口一致。具體實現上,是聚合了4和6兩個實體。所以提供is_v4 is_v6這樣兩個函數來確認類型。
              address只提供string到address的轉換和構造。具體到address_v6 address_v4以后有提供long到address_v4的轉換同時也提供了一系列的幫助函數:
                /// Determine whether the address is a loopback address.
              BOOST_ASIO_DECL bool is_loopback() const;

              /// Determine whether the address is unspecified.
              BOOST_ASIO_DECL bool is_unspecified() const;

              /// Determine whether the address is a class A address.
              BOOST_ASIO_DECL bool is_class_a() const;

              /// Determine whether the address is a class B address.
              BOOST_ASIO_DECL bool is_class_b() const;

              /// Determine whether the address is a class C address.
              BOOST_ASIO_DECL bool is_class_c() const;

              /// Determine whether the address is a multicast address.
              BOOST_ASIO_DECL bool is_multicast() const;
              /// Obtain an address object that represents the loopback address.
              static address_v4 loopback()
              /// Obtain an address object that represents the broadcast address.
              static address_v4 broadcast()

            posted @ 2012-11-06 10:46 Enic 閱讀(521) | 評論 (0)編輯 收藏

            C 宏

            1,防止一個頭文件被重復包含
            #ifndef BODYDEF_H
            #define BODYDEF_H
            //頭文件內容
            #endif
            2,得到指定地址上的一個字節或字
            #define MEM_B( x ) ( *( (byte *) (x) ) )
            #define MEM_W( x ) ( *( (word *) (x) ) )
            3,得到一個field在結構體(struct)中的偏移量
            #define FPOS( type, field ) ( (dword) &(( type *) 0)-> field )
            4,得到一個結構體中field所占用的字節數
            #define FSIZ( type, field ) sizeof( ((type *) 0)->field )
            5,得到一個變量的地址(word寬度)
            #define B_PTR( var ) ( (byte *) (void *) &(var) )
            #define W_PTR( var ) ( (word *) (void *) &(var) )
            6,將一個字母轉換為大寫
            #define UPCASE( c ) ( ((c) >= ''a'' && (c) <= ''z'') ? ((c) - 0x20) : (c) )
            7,判斷字符是不是10進值的數字
            #define DECCHK( c ) ((c) >= ''0'' && (c) <= ''9'')
            8,判斷字符是不是16進值的數字
            #define HEXCHK( c ) ( ((c) >= ''0'' && (c) <= ''9'') ||((c) >= ''A'' && (c) <= ''F'') ||((c) >= ''a'' && (c) <= ''f'') )
            9,防止溢出的一個方法
            #define INC_SAT( val ) (val = ((val)+1 > (val)) ? (val)+1 : (val))
            10,返回數組元素的個數
            #define ARR_SIZE( a ) ( sizeof( (a) ) / sizeof( (a[0]) ) )
            11,使用一些宏跟蹤調試
            ANSI標準說明了五個預定義的宏名。它們是:
            _LINE_ (兩個下劃線),對應%d
            _FILE_     對應%s
            _DATE_   對應%s
            _TIME_    對應%s
            _STDC_


            宏中"#"和"##"的用法
            我們使用#把宏參數變為一個字符串,用##把兩個宏參數貼合在一起.
            #define STR(s)     #s
            #define CONS(a,b) int(a##e##b)
            Printf(STR(vck));           // 輸出字符串"vck"
            printf("%d\n", CONS(2,3)); // 2e3 輸出:2000

            當宏參數是另一個宏的時候
            需要注意的是凡宏定義里有用"#"或"##"的地方宏參數是不會再展開.
            #define A          (2)
            #define STR(s)     #s
            #define CONS(a,b) int(a##e##b)
            printf("%s\n", CONS(A, A));               // compile error
            這一行則是:
            printf("%s\n", int(AeA));
            INT_MAX和A都不會再被展開, 然而解決這個問題的方法很簡單. 加多一層中間轉換宏.
            加這層宏的用意是把所有宏的參數在這層里全部展開, 那么在轉換宏里的那一個宏(_STR)就能得到正確的宏參數
            #define STR(s)      _STR(s)          // 轉換宏
            #define CONS(a,b)   _CONS(a,b)       // 轉換宏
            printf("int max: %s\n", STR(INT_MAX));          // INT_MAX,int型的最大值,為一個變量 #i nclude<climits>
            輸出為: int max: 0x7fffffff
            STR(INT_MAX) --> _STR(0x7fffffff) 然后再轉換成字符串;

            printf("%d\n", CONS(A, A));
            輸出為:200
            CONS(A, A) --> _CONS((2), (2)) --> int((2)e(2))

            "#"和"##"的一些應用特例
            1、合并匿名變量名
            #define ___ANONYMOUS1(type, var, line) type var##line
            #define __ANONYMOUS0(type, line) ___ANONYMOUS1(type, _anonymous, line)
            #define ANONYMOUS(type) __ANONYMOUS0(type, __LINE__)
            例:ANONYMOUS(static int); 即: static int _anonymous70; 70表示該行行號;
            第一層:ANONYMOUS(static int); --> __ANONYMOUS0(static int, __LINE__);
            第二層:                        --> ___ANONYMOUS1(static int, _anonymous, 70);
            第三層:                        --> static int _anonymous70;
            即每次只能解開當前層的宏,所以__LINE__在第二層才能被解開;

            注備:這里面的解釋 有點牽強。真正的解釋是這樣的:

               【宏參數的prescan】
               當一個宏參數被放進宏體時,這個宏參數會首先被全部展開(有例外,見下文)。當展開后的宏參數被放進宏體時,
               預處理器對新展開的宏體進行第二次掃描,并繼續展開。例如:
               #define PARAM( x ) x
               #define ADDPARAM( x ) INT_##x
               PARAM( ADDPARAM( 1 ) );
               因為ADDPARAM( 1 ) 是作為PARAM的宏參數,所以先將ADDPARAM( 1 )展開為INT_1,然后再將INT_1放進PARAM。
              
               例外情況是,如果PARAM宏里對宏參數使用了#或##,那么宏參數不會被展開:
               #define PARAM( x ) #x
               #define ADDPARAM( x ) INT_##x
               PARAM( ADDPARAM( 1 ) ); 將被展開為"ADDPARAM( 1 )"。

               使用這么一個規則,可以創建一個很有趣的技術:打印出一個宏被展開后的樣子,這樣可以方便你分析代碼:
               #define TO_STRING( x ) TO_STRING1( x )
               #define TO_STRING1( x ) #x
               TO_STRING首先會將x全部展開(如果x也是一個宏的話),然后再傳給TO_STRING1轉換為字符串,現在你可以這樣:
               const char *str = TO_STRING( PARAM( ADDPARAM( 1 ) ) );去一探PARAM展開后的樣子。

              預處理器的確是從內到外展開宏的

            2、填充結構
            #define FILL(a)   {a, #a}

            enum IDD{OPEN, CLOSE};
            typedef struct MSG{
            IDD id;
            const char * msg;
            }MSG;

            MSG _msg[] = {FILL(OPEN), FILL(CLOSE)};
            相當于:
            MSG _msg[] = {{OPEN, "OPEN"},
                          {CLOSE, "CLOSE"}};

            3、記錄文件名
            #define _GET_FILE_NAME(f)   #f
            #define GET_FILE_NAME(f)    _GET_FILE_NAME(f)
            static char FILE_NAME[] = GET_FILE_NAME(__FILE__);

            4、得到一個數值類型所對應的字符串緩沖大小
            #define _TYPE_BUF_SIZE(type) sizeof #type
            #define TYPE_BUF_SIZE(type)   _TYPE_BUF_SIZE(type)
            char buf[TYPE_BUF_SIZE(INT_MAX)];
                 --> char buf[_TYPE_BUF_SIZE(0x7fffffff)];
                 --> char buf[sizeof "0x7fffffff"];
            這里相當于:
            char buf[11];

            posted @ 2012-11-02 17:40 Enic 閱讀(461) | 評論 (2)編輯 收藏

            前言
            第1章并行讓程序運行得更快
            你可能會想到的一些問題
            采用線程化方法的4個步驟
            并行算法的背景知識
            共享內存編程與分布式內存編程的比較
            本書采用的并發編程方法
            第2章是否采用并發
            并發算法的設計模型
            哪些算法不能并行
            第3章算法正確性證明與性能衡量
            并行算法的驗證
            示例:臨界區問題
            性能測試(程序的執行情況如何)
            硬件并行性的發展歷史

            第4章多線程程序設計中的8條簡單規則
            規則1:找出真正獨立的運算
            規則2:在盡可能高的層次上實現并發
            規則3:盡早考慮通過增加處理器核的數量來獲得可伸縮性
            規則4:盡可能使用線程安全的庫
            規則5:使用正確的多線程模型
            規則6:永遠不要假設程序會按照某種特定的順序執行
            規則7:盡可能使用線程局部存儲或者與特定數據相關的鎖
            規則8:要敢于對代碼進行修改以獲得更好的并發性
            小結

            第5章線程化庫
            隱式線程化
            顯式線程化
            其他主題
            特定領域的庫

            第6章并行求和與前綴求和
            并行求和
            前綴求和
            選擇
            最后的思考
            第7章映射歸約
            并發映射運算
            并發歸約運算
            映射歸約的應用
            映射歸約作為一般性并發

            第8章排序
            冒泡排序
            奇偶換位排序
            希爾排序
            快速排序
            基數排序

            第9章搜索
            未排序的數據序列
            二分搜索

            第10章圖算法
            深度優先搜索
            最短路徑問題
            最小生成樹

            第11章線程化工具
            調試器
            性能工具
            其他主題
            再接再厲

            posted @ 2012-10-23 09:30 Enic 閱讀(285) | 評論 (0)編輯 收藏

            image

            這個體系中的class職責如下:

            *ios_base:定義stream classes的所有“與字符類型以及相應的字符特性(traits)無關”的屬性,主要包含狀態和格式標志等組件和函數。

            *basic_ios<>:定義“與字符類型以及相應的字符特性(traits)相關”的stream classes共同屬性,其中包括stream所用的緩沖器。

            *basic_istream<>  basic_ostream<>:定義出讀寫對象,如果不關心國際化問題,一般直接使用char實例化的isteram和ostream。

            *basic_iostream<>:讀寫對象。

            *basic_streambuf<>:iostream體系的核心,定義出所有“可改寫的stream或,可讀取的stream”的接口。其他的stream classes都是利用它進行實際的字符讀寫操作。

             

                iostream程序嚴格按照職責分離的原則來設計。basic_ios派生類型只處理數據格式化,實際讀寫操作由basic_ios派生類所維護的stream buffer完成。streambuf提供讀寫使用的字符緩沖區,形成對外的一種抽象概念。

            posted @ 2012-10-22 14:41 Enic 閱讀(187) | 評論 (0)編輯 收藏

             

            image                                                                                        

            #include <iostream>

            #include <boost/timer.hpp>

            int _tmain(int argc, _TCHAR* argv[])
            {
                boost::timer timer;

                const unsigned int TEST_DATA_LEN = 1440*900;
                char* pDataA = new char[TEST_DATA_LEN];
                memset(pDataA, NULL, TEST_DATA_LEN);
                char* pDataB = new char[TEST_DATA_LEN];
                memset(pDataB, NULL, TEST_DATA_LEN);

                double dCopyTime = 0;
                timer.restart();
                for (unsigned int uiLen = 0; uiLen < 1020; uiLen++)
                {
                    memcpy(pDataA, pDataB, TEST_DATA_LEN);
                }
                dCopyTime = timer.elapsed();
                std::cout << dCopyTime << std::endl;

                double dMoveTime = 0;
                timer.restart();
                for (unsigned int uiLen = 0; uiLen < 1020; uiLen++)
                {
                    memmove(pDataA, pDataA, TEST_DATA_LEN);
                }
                dMoveTime = timer.elapsed();
                std::cout << dMoveTime << std::endl;

                std::cout << "self copy lost:" << (dMoveTime - dCopyTime)*100 << std::endl;

                return 0;
            }

            posted @ 2012-10-16 11:51 Enic 閱讀(262) | 評論 (0)編輯 收藏

            // test_demo.cpp : 定義控制臺應用程序的入口點。
            //

            #include "stdafx.h"

            #include <iostream>

            class L1Provider
            {
            public:
                virtual void L1Service() = 0;
            };

            class L2Provider
            {
            public:
                virtual void L2Service() = 0;
                void SetLowerLayer(L1Provider* lv1)
                {
                    m_pLv1 = lv1;
                }

            protected:
                L1Provider* m_pLv1;
            };

            class L3Provider
            {
            public:
                virtual void L3Service() = 0;
                void SetLowerLayer(L2Provider* lv2)
                {
                    m_pLv2 = lv2;
                }

            protected:
                L2Provider* m_pLv2;
            };

            class DataLink : public L1Provider
            {
            public:
                virtual void L1Service()
                {
                    std::cout << "lv1 doing its job" << std::endl;
                }
            };

            class Transport : public L2Provider
            {
            public:
                virtual void L2Service()
                {
                    std::cout << "lv2 start its job" << std::endl;
                    m_pLv1->L1Service();
                    std::cout << "lv2 end its job" << std::endl;
                }
            };

            class Session : public L3Provider
            {
            public:
                virtual void L3Service()
                {
                    std::cout << "lv3 start its job" << std::endl;
                    m_pLv2->L2Service();
                    std::cout << "lv3 end its job" << std::endl;
                }
            };

            int _tmain(int argc, _TCHAR* argv[])
            {
                // 實例化個層對象
                DataLink dataLink;
                Transport transport;
                Session session;

                // 安裝好層
                transport.SetLowerLayer(&dataLink);
                session.SetLowerLayer(&transport);

                // 工作
                session.L3Service();

                return 0;
            }

            posted @ 2012-10-12 13:44 Enic 閱讀(151) | 評論 (0)編輯 收藏

                 摘要: 簡化后的CNetClient類圖:   本次是分享下整體設計思想,不研究細節網絡實現。     CNetClient用戶客戶端的網絡處理。主要功能需求如下: *能接收遠端數據 *能把接收到的數據送到上層處理 *能向遠端發送數據 **發送和接收都是異步 **CNetClient本身是一個底層服務,對上層是異步的   針對上述需求GodofMon...  閱讀全文
            posted @ 2012-10-11 17:34 Enic 閱讀(412) | 評論 (0)編輯 收藏

             

            ///////////////////////////////////////////////////////////////////////////////////////////

            實在是沒看出來這樣有什么優勢,為了記錄是否走過某個path?

            Query::execute(const SQLString& str)這里看到了遞歸操作,難道是為了輔助遞歸?

            總感覺這里越搞越復雜,,,

            ///////////////////////////////////////////////////////////////////////////////////////////

            /// \brief A template for setting a flag on a variable as long as the
            /// object that set it is in scope.  Flag resets when object goes
            /// out of scope.  Works on anything that looks like bool.

            template <class T = bool>
            class AutoFlag
            {
            public:
                /// \brief Constructor: sets ref to true.
                AutoFlag(T& ref) :
                referent_(ref)
                {
                    referent_ = true;
                }

                /// \brief Destructor: sets referent passed to ctor to false.
                ~AutoFlag()
                {
                    referent_ = false;
                }

            private:
                T& referent_;
            };

             

            ///////////////////////////////////////////////////////////////////////////////////////////

            ResNSel
            Query::execute(const SQLString& str)
            {
                if ((def.size() == 1) && !def.processing_) {
                    // .  The
                    // auto-reset flag is required because we'll end up back in this
                    // function once the query string is built, but we need to take
                    // the 'else' path to avoid an infinite loop.
                    AutoFlag<> af(def.processing_);
                    return execute(SQLQueryParms() << str);
                }
                else {
                    // Take str to be the entire query string
                    return execute(str.c_str(), str.length());
                }
            }

            ResNSel
            Query::execute(const char* str)
            {
                return execute(SQLString(str));
            }

            ResNSel
            Query::execute(const char* str, size_t len)
            {
                if (lock()) {
                    success_ = false;
                    if (throw_exceptions()) {
                        throw LockFailed();
                    }
                    else {
                        return ResNSel();
                    }
                }

                success_ = !mysql_real_query(&conn_->mysql_, str, len);

                unlock();
                if (success_) {
                    return ResNSel(conn_);
                }
                else if (throw_exceptions()) {
                    throw BadQuery(error());
                }
                else {
                    return ResNSel();
                }
            }

            posted @ 2012-10-08 11:51 Enic 閱讀(114) | 評論 (0)編輯 收藏

            ////////////////////////////////////////////////////////////////

            簡介:內存DC,又名“雙緩沖”,是解決windows窗口自繪中出現“閃屏”的常規手段。

            1)、為屏幕 DC 創建兼容的內存 DC
            2)、創建位圖
            3)、把位圖選入設備環境
            4)、把繪制好的圖形“拷貝“到屏幕上

             

            看這個代碼:

            首先看構造,從一個CDC構造。然后看了一下成員函數,好像沒幾個,估計這是一個可以完全替換的CDC的省心的東東。

            然后看析構:析構是一個BitBit,聯想自己做內存DC的時候,最后一步也是內存到DC的貼圖動作。

            公開接口就兩個,重載的CDC* 和 ->操作,直接能當作CDC使用。

            這幾個細節需要注意:

            1.m_bMemDC = !pDC->IsPrinting();  // 以前關注不多,這是用于判斷這個DC是不是用于print,如果是就不使用“內存DC”,至于為什么還不了解。我理解是沒有需要。

            2.FillSolidRect(m_rect, pDC->GetBkColor());  // WM_ERASEBKGND,針對這個消息的細節處理。

             

            這個類持有了一個“前臺”DC,它本身是一個“后臺”DC,每次后臺克隆前臺執行繪畫然后把結果貼回去。

            這里還有一個細節,就是SelectObject。為了保證不泄漏,最好的辦法是,每次工作完成將所有的GDI對象復位。

            ///////////////////////////////////////////////////////////////

            class CMemDC : public CDC
            {
            public:

                // constructor sets up the memory DC
                CMemDC(CDC* pDC) : CDC()
                {
                    ASSERT(pDC != NULL);

                    m_pDC = pDC;
                    m_pOldBitmap = NULL;
            #ifndef _WIN32_WCE_NO_PRINTING
                    m_bMemDC = !pDC->IsPrinting();
            #else
                    m_bMemDC = FALSE;
            #endif

                    if (m_bMemDC)    // Create a Memory DC
                    {
                        pDC->GetClipBox(&m_rect);
                        CreateCompatibleDC(pDC);
                        m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height());
                        m_pOldBitmap = SelectObject(&m_bitmap);
            #ifndef _WIN32_WCE
                        SetWindowOrg(m_rect.left, m_rect.top);
            #endif
                        // EFW - Bug fix - Fill background in case the user has overridden
                        // WM_ERASEBKGND.  We end up with garbage otherwise.
                        // CJM - moved to fix a bug in the fix.
                        FillSolidRect(m_rect, pDC->GetBkColor());
                    }
                    else        // Make a copy of the relevent parts of the current DC for printing
                    {
            #if !defined(_WIN32_WCE) || ((_WIN32_WCE > 201) && !defined(_WIN32_WCE_NO_PRINTING))
                        m_bPrinting = pDC->m_bPrinting;
            #endif
                        m_hDC       = pDC->m_hDC;
                        m_hAttribDC = pDC->m_hAttribDC;
                    }

                }

                // Destructor copies the contents of the mem DC to the original DC
                ~CMemDC()
                {
                    if (m_bMemDC)
                    {
                        // Copy the offscreen bitmap onto the screen.
                        m_pDC->BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(),
                                      this, m_rect.left, m_rect.top, SRCCOPY);

                        //Swap back the original bitmap.
                        SelectObject(m_pOldBitmap);
                    } else {
                        // All we need to do is replace the DC with an illegal value,
                        // this keeps us from accidently deleting the handles associated with
                        // the CDC that was passed to the constructor.
                        m_hDC = m_hAttribDC = NULL;
                    }
                }

                // Allow usage as a pointer
                CMemDC* operator->() {return this;}
                // Allow usage as a pointer
                operator CMemDC*() {return this;}

            private:
                CBitmap  m_bitmap;      // Offscreen bitmap
                CBitmap* m_pOldBitmap;  // bitmap originally found in CMemDC
                CDC*     m_pDC;         // Saves CDC passed in constructor
                CRect    m_rect;        // Rectangle of drawing area.
                BOOL     m_bMemDC;      // TRUE if CDC really is a Memory DC.
            };

            posted @ 2012-10-08 10:41 Enic 閱讀(227) | 評論 (0)編輯 收藏

            #include <iostream>
            #include <string>
            #include <locale>
            #include <codecvt>
            #include <fstream>
            int main(int argc, char *argv[])
            {
               std::wstring str = L"123,我是誰?我愛釣魚島!";
               std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
               std::string narrowStr = conv.to_bytes(str);
               {
                  std::ofstream ofs ("c:\\test.txt");
                  ofs << narrowStr;
               }
               std::wstring wideStr = conv.from_bytes(narrowStr);
               {
                  std::locale::global(std::locale("Chinese-simplified"));
                  std::wofstream ofs (L"c:\\testW.txt");
                  ofs << wideStr;
               }

            posted @ 2012-09-12 13:37 Enic 閱讀(109) | 評論 (0)編輯 收藏

            僅列出標題
            共22頁: First 14 15 16 17 18 19 20 21 22 
            久久99精品免费一区二区| 久久综合精品国产二区无码| 国产精品久久久久久久午夜片 | 亚洲国产精品无码久久九九| 久久精品国产亚洲AV无码娇色| 久久综合久久鬼色| 97超级碰碰碰碰久久久久| 亚洲AV无一区二区三区久久| 久久99精品久久久久久9蜜桃| 久久99热这里只频精品6| 久久久久综合中文字幕 | 2020最新久久久视精品爱| 久久综合亚洲色HEZYO国产| 精品无码久久久久久尤物| 精品国产乱码久久久久久呢| 久久久久久曰本AV免费免费| 2021少妇久久久久久久久久| 国产精品无码久久综合| 亚洲国产天堂久久综合| 精品一久久香蕉国产线看播放| 久久精品国产亚洲AV无码偷窥| 久久伊人五月丁香狠狠色| 久久e热在这里只有国产中文精品99| 久久久无码精品亚洲日韩蜜臀浪潮| 国产69精品久久久久99| 国产一级持黄大片99久久| 中文字幕一区二区三区久久网站| 亚洲中文字幕久久精品无码喷水| 亚洲AV日韩精品久久久久久 | 国内精品伊人久久久久妇| 国産精品久久久久久久| 国产精品久久国产精品99盘 | 国产精品久久久久久久久久免费| 国产成人精品久久免费动漫| 亚洲国产精品久久电影欧美| 亚洲精品国产美女久久久| 亚洲精品乱码久久久久久中文字幕 | 亚洲国产精品久久久天堂| 日韩人妻无码一区二区三区久久 | 国内精品伊人久久久久av一坑| 日韩精品久久久肉伦网站|