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

            colorful

            zc qq:1337220912

             

            why enable_shared_from_this

             為什么會(huì)有 tr1::enable_shared_from_this 這個(gè)類,一直不解,直到看了Stephan T. Lavavej給出的關(guān)于shared_ptr 的PPT。 Stephan T. Lavavej是Visual C++ Libraries Developer。

            他給的例子是:

            struct Ansible {
                shared_ptr<Ansible> get_shared() {
                    shared_ptr<Ansible> ret(this);
                    return ret;
                }
            };

            int main() {
                shared_ptr<Ansible> a(new Ansible);
                Ansible& r = *a;
                shared_ptr<Ansible> b = r.get_shared();
            }

            Result: DOUBLE DELETION


            然后使用enable_shared_from_this 就對(duì)了:

            struct Ansible
                : public enable_shared_from_this<Ansible> { };

            int main() {
                shared_ptr<Ansible> a(new Ansible);
                Ansible& r = *a;
                shared_ptr<Ansible> b = r.shared_from_this();
            }

            a and b share ownership, as if:
            shared_ptr<Ansible> b = a;



            為什么?看看enable_shared_from_this 的實(shí)現(xiàn)://也可看boost

            template<class _Ty> class enable_shared_from_this
             { // provide member functions that create shared_ptr to this
            public:
             typedef _Ty _EStype;

             shared_ptr<_Ty> shared_from_this()
              { // return shared_ptr
              return shared_ptr<_Ty>(_Wptr);
              }

             shared_ptr<const _Ty> shared_from_this() const
              { // return shared_ptr
              return shared_ptr<const _Ty>(_Wptr);
              }

            protected:
             enable_shared_from_this()
              { // construct (do nothing)
              }

             enable_shared_from_this(const enable_shared_from_this& _Right)
              : _Wptr(_Right._Wptr)
              { // construct
              }

             enable_shared_from_this& operator=(const enable_shared_from_this& _Right)
              { // assign
              _Wptr = _Right._Wptr;
              return *this;
              }

             ~enable_shared_from_this()
              { // destroy (do nothing)
              }

            private:
             template<class _Ty1,
              class _Ty2>
              friend void _Do_enable(
               _Ty1 *,
               enable_shared_from_this<_Ty2>*,
               _Ref_count_base *);

             mutable weak_ptr<_Ty> _Wptr;
             };


            enable_shared_from_this 的member可是一個(gè)weak_ptr.

            當(dāng)然,從enable_shared_from_this繼承后,遇到shared_ptr后,member _Wptr 是怎樣工作的,另有玄機(jī)。 可以設(shè)斷點(diǎn)在 _Do_enable 里,有助于理解。

            看似簡(jiǎn)單的share_ptr, 被實(shí)現(xiàn)的看似危機(jī)四伏。

            posted @ 2012-04-07 11:57 多彩人生 閱讀(428) | 評(píng)論 (0)編輯 收藏

            mutable關(guān)鍵字

            mutalbe的中文意思是“可變的,易變的”,跟constant(既C++中的const)是反義詞。

              在C++中,mutable也是為了突破const的限制而設(shè)置的。被mutable修飾的變量,將永遠(yuǎn)處于可變的狀態(tài),即使在一個(gè)const函數(shù)中。

              我們知道,如果類的成員函數(shù)不會(huì)改變對(duì)象的狀態(tài),那么這個(gè)成員函數(shù)一般會(huì)聲明成const的。但是,有些時(shí)候,我們需要在const的函數(shù)里面修改一些跟類狀態(tài)無關(guān)的數(shù)據(jù)成員,那么這個(gè)數(shù)據(jù)成員就應(yīng)該被mutalbe來修飾。

              下面是一個(gè)小例子:

            class ClxTest
            {
             public:
              void Output() const;
            };

            void ClxTest::Output() const
            {
             cout << "Output for test!" << endl;
            }

            void OutputTest(const ClxTest& lx)
            {
             lx.Output();
            }

              類ClxTest的成員函數(shù)Output是用來輸出的,不會(huì)修改類的狀態(tài),所以被聲明為const的。

              函數(shù)OutputTest也是用來輸出的,里面調(diào)用了對(duì)象lx的Output輸出方法,為了防止在函數(shù)中調(diào)用其他成員函數(shù)修改任何成員變量,所以參數(shù)也被const修飾。

               如果現(xiàn)在,我們要增添一個(gè)功能:計(jì)算每個(gè)對(duì)象的輸出次數(shù)。如果用來計(jì)數(shù)的變量是普通的變量的話,那么在const成員函數(shù)Output里面是不能修改該 變量的值的;而該變量跟對(duì)象的狀態(tài)無關(guān),所以應(yīng)該為了修改該變量而去掉Output的const屬性。這個(gè)時(shí)候,就該我們的mutable出場(chǎng)了——只要 用mutalbe來修飾這個(gè)變量,所有問題就迎刃而解了。

              下面是修改過的代碼:

            class ClxTest
            {
             public:
              ClxTest();
              ~ClxTest();

              void Output() const;
              int GetOutputTimes() const;

             private:
              mutable int m_iTimes;
            };

            ClxTest::ClxTest()
            {
             m_iTimes = 0;
            }

            ClxTest::~ClxTest()
            {}

            void ClxTest::Output() const
            {
             cout << "Output for test!" << endl;
             m_iTimes++;
            }

            int ClxTest::GetOutputTimes() const
            {
             return m_iTimes;
            }

            void OutputTest(const ClxTest& lx)
            {
             cout << lx.GetOutputTimes() << endl;
             lx.Output();
             cout << lx.GetOutputTimes() << endl;
            }

              計(jì)數(shù)器m_iTimes被mutable修飾,那么它就可以突破const的限制,在被const修飾的函數(shù)里面也能被修改。

            posted @ 2012-04-05 16:50 多彩人生 閱讀(245) | 評(píng)論 (0)編輯 收藏

            using namespace

            // myclass.h
            using namespace std;  // 所有包含myclass.h的文件對(duì)std都可見,  所以一般不要將它放在頭文件中,以免污染全局空間
            class myclass
            {
            }

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

            // myclass.h
            class myclass
            {
                  
            using namespace std;  // 錯(cuò), 不能放在類原型中
            }


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

            // myclass.h
            class myclass
            {
                 
            void foo()
                 {
                     
            using namespace std;   // 正確, std只本函數(shù)可見
                     list<int> col;
                 }
            }


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

            // myclass.h
            class myclass
            {
                  
            void foo();
            }

            // myclass.cpp
            void myclass::foo()
            {
                  
            using namespace std; // 正確, std只本函數(shù)可見
            }

            posted @ 2012-04-05 14:33 多彩人生 閱讀(196) | 評(píng)論 (0)編輯 收藏

            wxWidgets+boost::asio "socket_types.hpp(22) : fatal error C1189: #error : WinSock.h has already been included"

            http://blog.csdn.net/gzlyb/article/details/5870326

            因?yàn)閣xWidgets 里已經(jīng)include "Winsock.h"
            在網(wǎng)上找了解決方法:
            http://boost.2283326.n4.nabble.com/quot-WinSock-h-has-already-been-included-quot-problem-with-asio-and-VC-2010-td3574900.html
            兩種方法都可行

            "WinSock.h has already been included" : problem with asio and VC++2010

            Claude

            Hi!

            I use a boost asio library in my program. When I compile with Visual C++ obtain this error:

            [...]\boost_1_45_0\boost\asio\detail\socket_types.hpp(22): fatal error C1189: #error :  WinSock.h has already been included

            How can I fix this error?


            Reply | Threaded |   star

            Re: "WinSock.h has already been included" : problem with asio and VC++2010

            michi7x7-2

            > Hi!
            Hello,

            > I use a boost asio library in my program. When I compile with Visual C++
            > obtain this error:
            >
            > [...]\boost_1_45_0\boost\asio\detail\socket_types.hpp(22): fatal error
            > C1189: #error :  WinSock.h has already been included
            >
            > How can I fix this error?

            Try to include asio before including any other Windows-Headers, or use
            WinSock2.h instead of WinSock.

            Best Regards,

            michi7x7

            _______________________________________________
            Boost-users mailing list
            [hidden email]
            http://lists.boost.org/mailman/listinfo.cgi/boost-users
            Reply | Threaded |   star

            Re: "WinSock.h has already been included" : problem with asio and VC++2010

            Hee-young Kim
            In reply to this post by Claude
            If you use "Windows.h" library, set "#define WIN32_LEAN_AND_MEAN" in "stdafx.h" or a suitable place to avoid the duplication.

            from Hee-young
            Reply | Threaded |   star

            Re: "WinSock.h has already been included" : problem with asio and VC++2010

            Claude
            I solved the problem, thanks!

            posted @ 2012-04-05 13:25 多彩人生 閱讀(2723) | 評(píng)論 (0)編輯 收藏

            Double-checked locking真的有效嗎?

            Double-checked locking真的有效嗎?

            作者: zsxwing 日期: 2011-04-29 10:48:06

            在很多設(shè)計(jì)模式的書籍中,我們都可以看到類似下面的單例模式的實(shí)現(xiàn)代碼,一般稱為Double-checked locking(DCL)

            01public class Singleton {
            02 
            03    private static Singleton instance;
            04 
            05    private Singleton() {
            06        // do something
            07    }
            08 
            09    public static Singleton getInstance() {
            10        if (instance == null) {//1
            11            synchronized (Singleton.class) {//2
            12                if (instance == null) {//3
            13                    instance = new Singleton();//4
            14                }
            15            }
            16        }
            17        return instance;
            18    }
            19}

            這樣子的代碼看起來很完美,可以解決instance的延遲初始化。只是,事實(shí)往往不是如此。

            問題在于instance = new Singleton();這行代碼。

            在我們看來,這行代碼的意義大概是下面這樣子的

             

             

            	mem = allocate();             //收集內(nèi)存 
            ctorSingleton(mem); //調(diào)用構(gòu)造函數(shù)
            instance = mem; //把地址傳給instance
            	

             

            這行代碼在Java虛擬機(jī)(JVM)看來,卻可能是下面的三個(gè)步驟(亂序執(zhí)行的機(jī)制):

             

            	mem = allocate();             //收集內(nèi)存 
            instance = mem; //把地址傳給instance
            	ctorSingleton(instance);      //調(diào)用構(gòu)造函數(shù)

             

            下面我們來假設(shè)一個(gè)場(chǎng)景。

            1. 線程A調(diào)用getInstance函數(shù)并且執(zhí)行到//4。但是線程A只執(zhí)行到賦值語句,還沒有調(diào)用構(gòu)造函數(shù)。此時(shí),instance已經(jīng)不是null了,但是對(duì)象還沒有初始化。
            2. 很不幸線程A這時(shí)正好被掛起。
            3. 線程B獲得執(zhí)行的權(quán)力,然后也開始調(diào)用getInstance。線程B在//1發(fā)現(xiàn)instance已經(jīng)不是null了,于是就返回對(duì)象了,但是這個(gè)對(duì)象還沒有初始化,于是對(duì)這個(gè)對(duì)象進(jìn)行操作就出錯(cuò)了。

            問題就出在instance被提前初始化了。

            解決方案一,不使用延遲加載:

            01public class Singleton {
            02 
            03    private static Singleton instance = new Singleton();
            04 
            05    private Singleton() {
            06        // do something
            07    }
            08 
            09    public static Singleton getInstance() {
            10        return instance;
            11    }
            12}

            JVM內(nèi)部的機(jī)制能夠保證當(dāng)一個(gè)類被加載的時(shí)候,這個(gè)類的加載過程是線程互斥的。這樣當(dāng)我們第一次調(diào)用getInstance的時(shí)候,JVM能夠幫我們保證instance只被創(chuàng)建一次,并且會(huì)保證把賦值給instance的內(nèi)存初始化完畢。

            解決方案二,利用一個(gè)內(nèi)部類來實(shí)現(xiàn)延遲加載:

            01public class Singleton {
            02 
            03    private Singleton() {
            04        // do something
            05    }
            06 
            07    private static class SingletonContainer {
            08        private static Singleton instance = new Singleton();
            09    }
            10 
            11    public static Singleton getInstance() {
            12        return SingletonContainer.instance;
            13    }
            14}

            這兩種方案都是利用了JVM的類加載機(jī)制的互斥。

            方案二的延遲加載實(shí)現(xiàn)是因?yàn)椋挥性诘谝淮握{(diào)用Singleton.getInstance()函數(shù)時(shí),JVM才會(huì)去加載SingletonContainer,并且初始化instance。

            不只Java存在這個(gè)問題,C/C++由于CPU的亂序執(zhí)行機(jī)制,也同樣存在這樣的問題。

            抱歉,我之前的理解有誤,DCL在Java中失效的原因是JIT比較激進(jìn)的優(yōu)化導(dǎo)致的,在C/C++并不會(huì)由于CPU的亂序執(zhí)行(調(diào)用構(gòu)造函數(shù)和賦值這兩個(gè)操作對(duì)CPU來說絕對(duì)不會(huì)亂序的)產(chǎn)生這個(gè)問題。

            暫時(shí)不知道Java對(duì)于這個(gè)問題是否修復(fù)了。

            posted @ 2012-03-31 16:53 多彩人生 閱讀(322) | 評(píng)論 (0)編輯 收藏

            偉大架構(gòu)師的秘密

            http://msdn.microsoft.com/zh-cn/library/aa480041.aspx

            所有偉大的架構(gòu)師都掌握了在抽象的不同層次上概念化解決方案的技能。通過將解決方案組織到離散的層次,架構(gòu)師可以專注于解決方案的單個(gè)方面而忽略所有剩余的復(fù)雜性。展示將抽象層次應(yīng)用到 IT 解決方案的技術(shù),并將其與其他工程學(xué)科相比較。

            一些架構(gòu)師在這種復(fù)雜性方面明顯非常出色,而且在不斷進(jìn)步。在我們的職業(yè)生涯中,能與一些真正偉大的分析師和架構(gòu)師并肩工作是非常幸運(yùn)的。反思這些經(jīng)驗(yàn),我們已經(jīng)分析出是什么造就了杰出的架構(gòu)師。

            無 一例外,所有偉大的架構(gòu)師都掌握了在截然不同的抽象層次上概念化解決方案的技能。通過將解決方案組織到離散的層次,架構(gòu)師可以將精力集中在解決方案的單個(gè) 方面而忽略所有剩余的復(fù)雜性。他們一旦穩(wěn)定了解決方案的某個(gè)部分,接下來就能繼續(xù)處理其他方面,從而不斷地將層次發(fā)展并完善到最終可以被實(shí)現(xiàn)的粘合模型 中。

            大多數(shù)軟件開發(fā)人員懂得應(yīng)該將解決方案分解到抽象層次。但是在實(shí)際的項(xiàng)目中,這是非常難于付諸實(shí)踐的。當(dāng)遇到第一個(gè)困難時(shí),在急于開 始編碼時(shí)是很容易放棄這些層次的。偉大的架構(gòu)師會(huì)經(jīng)受這些挑戰(zhàn)并在整個(gè)項(xiàng)目的生命周期中嚴(yán)格保持這些層次。他們意識(shí)到,如果不這樣做,最終將淹沒在復(fù)雜性 中。


            posted @ 2012-03-31 11:05 多彩人生 閱讀(341) | 評(píng)論 (0)編輯 收藏

            boost::asio::deadline_timer

            注意deadline_timer和socket一樣,都用 io_service作為構(gòu)造函數(shù)的參數(shù)。也即,在其上進(jìn)行異步操作,都將導(dǎo)致和io_service所包含的iocp相關(guān)聯(lián)。這同樣意味著在析構(gòu) io_service之前,必須析構(gòu)關(guān)聯(lián)在這個(gè)io_service上的deadline_timer。

            一個(gè)deadline_timer只維護(hù)一個(gè)超時(shí)時(shí)間,一個(gè)deadline_timer不同時(shí)維持多個(gè)定時(shí)器。

            void wait();
            void
            wait(boost::system::error_code & ec);

            這是個(gè)同步等待函數(shù),例如:

            boost::asio::io_service io;
            boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));
            t.wait();
            由于不涉及到異步,該函數(shù)和io_service沒什么關(guān)系。這個(gè)函數(shù)在windows下的實(shí)現(xiàn)就只是簡(jiǎn)單的Sleep。因此也就不存在cancel之說。

            如果t的expire時(shí)間已過,那么t.wait會(huì)立刻返回。

            例如如下代碼:

            boost::asio::io_service io; 
            boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));
            t.wait();
            t.wait();

            第一個(gè)t.wait會(huì)等待5s才返回,第2個(gè)t.wait會(huì)立刻返回。

            wait函數(shù)本身沒有參數(shù),不存在t.wait(seconds(5))的用法。

            可以在構(gòu)造deadline_timer時(shí)指定時(shí)間。

            basic_deadline_timer(
            boost::asio::io_service & io_service);

            basic_deadline_timer(
            boost::asio::io_service & io_service,
            const time_type & expiry_time);

            basic_deadline_timer(
            boost::asio::io_service & io_service,
            const duration_type & expiry_time);

            注意后兩種的區(qū)別。以下2種用法是等價(jià)的:

            boost::asio::deadline_timer t(io, boost::posix_time::microsec_clock::universal_time()+boost::posix_time::seconds(5));

            boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));

            前者是絕對(duì)時(shí)間,后者是相對(duì)時(shí)間。

            除了在deadline_timer構(gòu)造函數(shù)中指定時(shí)間,也可以使用如下2個(gè)函數(shù)指定時(shí)間:

            expires_at,expires_from_now。這兩個(gè)函數(shù)的區(qū)別是前者參數(shù)是絕對(duì)時(shí)間,后者是相對(duì)時(shí)間。例如:

            boost::asio::io_service io;

            boost::asio::deadline_timer t(io);

            t.expires_from_now(boost::posix_time::seconds(5));

            t.wait();

            注意這兩個(gè)函數(shù)除了設(shè)定下次超時(shí)時(shí)間之外,還有一個(gè)效果是取消前面所有的異步wait。詳情參看關(guān)于這兩個(gè)函數(shù)的詳細(xì)解釋。

            template<
                typename
            WaitHandler>
            void async_wait(
                WaitHandler handler);
            其中void handler(
            const boost::system::error_code& error // Result of operation.
            );

            注意這個(gè)error很重要,表明這個(gè)handler是因?yàn)槌瑫r(shí)被執(zhí)行還是因?yàn)楸籧ancel。
            符合2種情況之一,handler被執(zhí)行:超時(shí)或者被cancel。
            這同時(shí)隱含的說明了除非io.stop被調(diào)用,否則handler一定會(huì)被執(zhí)行。即便是被cancel。
            被cancel有多種方法,直接調(diào)用cancel或者調(diào)用expires_at,expires_from_now重新設(shè)置超時(shí)時(shí)間。
            void handle_wait(const boost::system::error_code& error,
            boost::asio::deadline_timer& t,int& count)
            {
            if(!error)
            {
            std::cout<< count<<"\n";
            if(count++<5)
            {
            t.expires_from_now(boost::posix_time::seconds(1));
            t.async_wait(boost::bind(handle_wait,boost::asio::placeholders::error,
            boost::ref(t),boost::ref(count)));
            }
            }
            }

            int main()
            {
            boost::asio::io_service io;
            boost::asio::deadline_timer t(io);
            size_t a = t.expires_from_now(boost::posix_time::seconds(1));
            int count = 0;
            t.async_wait(boost::bind(handle_wait,boost::asio::placeholders::error,
            boost::ref(t),boost::ref(count)));
            io.run();
            return 0;
            }

            deadline_timer的析構(gòu)函數(shù)什么也不做,因此不會(huì)導(dǎo)致發(fā)出的async_wait被cancel。

            std::size_t cancel();

            std::size_t
            cancel(
                boost::system::error_code & ec);
            此函數(shù)調(diào)用會(huì)導(dǎo)致所有尚未返回的async_wait(handler)的handler被調(diào)用,同時(shí)error_code為boost::asio::error::operation_aborted。返回值是被cancel的timer數(shù)量。

             time_type expires_at() const;

            std::size_t
            expires_at(
            const time_type & expiry_time);

            std::size_t
            expires_at(
            const time_type & expiry_time,
            boost::system::error_code & ec);
            duration_type expires_from_now() const;

            std::size_t
            expires_from_now(
            const duration_type & expiry_time);

            std::size_t
            expires_from_now(
            const duration_type & expiry_time,
            boost::system::error_code & ec);
            以上2組函數(shù)用來設(shè)置新的超時(shí)時(shí)間,同時(shí)cancel所有未完成的async_wait操作。注意這兩個(gè)函數(shù)的返回值即為cancel的操作數(shù)量。
            考慮如下場(chǎng)景,我們有一個(gè)workerthread正在調(diào)用io_work.run();

            此時(shí)主線程向workerthread發(fā)出了一個(gè)異步調(diào)用,例如post(...),考慮到io_work.run很可能積壓了很多handlers沒有處理,或者某些handlers處理非常耗時(shí),希望它在5s內(nèi)必須返回。那么可以:

            void handle_wait(const boost::system::error_code& error,bool& Ret)
            {
                if(!error) Ret = false;
            }

            void handle_func(
                boost::shared_ptr<boost::asio::deadline_timer> t,
                boost::shared_ptr<boost::asio::io_service> io,
                int* v)
            {
                boost::asio::io_service::work work(*io);

                if(t->cancel()>0)
                {       
                    *v = 1;
                }
            }

            void func_delay_1_second()
            {
                boost::asio::io_service io;
                boost::asio::deadline_timer t(io,boost::posix_time::seconds(1));
                t.wait();
            }

            bool sync_func(int& v,boost::asio::io_service& io_work)
            {
                boost::shared_ptr<boost::asio::io_service> io(new boost::asio::io_service);
                boost::shared_ptr<boost::asio::deadline_timer> t(new boost::asio::deadline_timer(*io));
                t->expires_from_now(boost::posix_time::seconds(5));
                bool ret = true;
                t->async_wait(boost::bind(handle_wait,boost::asio::placeholders::error,boost::ref(ret)));
                io_work.post(boost::bind(handle_func,t,io,&v));
                io->run();
                return ret;
            }

            int main()
            {
                boost::asio::io_service io_work;
                auto_ptr<boost::asio::io_service::work> work(new boost::asio::io_service::work(io_work));
                boost::thread workthread(boost::bind(&boost::asio::io_service::run, &io_work));
                for(int i=0;i<3;++i) io_work.post(func_delay_1_second);

                int v = 0;
                bool ret = sync_func(v,io_work);
                if(ret) printf("v %d\n",v);

                work.reset();
                workthread.join();
                return 0;
            }

            上面代碼中如果先進(jìn)入handle_wait,則表明超時(shí),此時(shí)設(shè)置ret = false,然后io.run會(huì)退出,表明調(diào)用失敗,如果稍后進(jìn)入handle_func,則t->cancel會(huì)返回0,也不做任何操作。雖然在 io.run退出時(shí)會(huì)釋放v,但由于handle_func不做任何操作因此也不會(huì)引起任何安全問題。如果handle_func先進(jìn)入,則首先使用 work讓io.run不會(huì)退出,然后取消timer,并且設(shè)置,隨后work析構(gòu),io.run會(huì)退出。注意這里面的同步問題:如果先進(jìn)入 handle_wait,隨后進(jìn)入handle_func,那么handle_func中的t->cancel會(huì)返回0從而不做任何事。如果先進(jìn)入 handle_func,隨后進(jìn)入handle_wait,那么t->cancel或者返回0或者返回1,由于使用了work,io.run也不會(huì) 退出。注意這里的t和io都是shared_ptr的,否則因?yàn)槿绻鹔andle_wait先返回,則io.run會(huì)立刻退出并析 構(gòu),handle_func中將使用懸空的t和io,將導(dǎo)致非法操作。注意這里的io必須是shared_ptr的,如果 boost::asio::io_service::work work(*io); 改成work(t->get_ioservice());則t是有效的,而t所索引的io_service已經(jīng)無效了,同樣會(huì)導(dǎo)致非法操作。牢記 io_service的使用原則:必須首先析構(gòu)所有索引的其他對(duì)象之后才能析構(gòu)io_service。

            posted @ 2012-03-30 16:39 多彩人生 閱讀(2269) | 評(píng)論 (1)編輯 收藏

            RAII

             RAII是“資源獲取就是初始化”的縮語(Resource Acquisition Is Initialization),是一種利用對(duì)象生命周期來控制程序資源(如內(nèi)存、文件句柄、網(wǎng)絡(luò)連接、互斥量等等)的簡(jiǎn)單技術(shù)。   RAII 的一般做法是這樣的:在對(duì)象構(gòu)造時(shí)獲取資源,接著控制對(duì)資源的訪問使之在對(duì)象的生命周期內(nèi)始終保持有效,最后在對(duì)象析構(gòu)的時(shí)候釋放資源。借此,我們實(shí)際上把管理一份資源的責(zé)任托管給了一個(gè)對(duì)象。這種做法有兩大好處:   1,我們不需要顯式地釋放資源。   2,采用這種方式,對(duì)象所需的資源在其生命期內(nèi)始終保持有效 —— 我們可以說,此時(shí)這個(gè)類維護(hù)了一個(gè) invariant。這樣,通過該類對(duì)象使用資源時(shí),就不必檢查資源有效性的問題,可以簡(jiǎn)化邏輯、提高效率。

            posted @ 2012-03-29 21:20 多彩人生 閱讀(227) | 評(píng)論 (0)編輯 收藏

            wxWidgets

            安裝好以后首先要編譯。

            1、   登陸http://www.wxwidgets.org/,下載wxMSW-2.8.8-Setup.exe

            2、   運(yùn)行wxMSW-2.8.8-Setup.exe,將wxWidgets安裝到D:\wxWidgets-2.8.8

            3、   安裝完畢后還需要進(jìn)行編譯,要求有IDE,我用的是MS Visual Studio 2008

            4、   進(jìn)入D:\wxWidgets-2.8.8\build\msw,運(yùn)用MS Visual Studio 2008打開wx.dsw或者wx_dll.dsw(或者兩者都編譯),因?yàn)?/span>.dsw文件是vc6的工程文件,點(diǎn)確定將所有文件進(jìn)行轉(zhuǎn)換,然后點(diǎn)擊Build->Configuration Manager,彈出窗口,選擇Active solution configurationUnicode Debug或是別的,如果需要其中多個(gè)solution configuration,可以依次選中,然后依次按下F7Build solution,我分別選中了Unicode DebugUnicode Release,編譯完成后會(huì)在D:\wxWidgets-2.8.8\lib下生成vc_lib文件夾,其中包括生成的相應(yīng)的.lib等文件和 mswud文件夾。到此,wxWidgets安裝完畢。

            【注意】wxbase28ud.lib中的ud代表Unicode Dug版本,相應(yīng)地wxbase28u.lib中的u代表的是UnicodeRelease版本。Unicode是統(tǒng)一的字符編碼標(biāo)準(zhǔn),采用雙字節(jié)對(duì)字符進(jìn)行編碼,支持多語言,有利于國(guó)際化,處理更方便,所以選擇編譯成Unicode版本。


            工程中需要添加 wxWidget 的頭文件目錄:

            %installdir%\include\msvc
            %installdir%\include

            以及庫(kù)目錄:

            %installdir%\lib\vc_lib

            另外如果是普通 Win32 工程的話,還需要鏈接額外的庫(kù):

            comctl32.lib rpcrt4.lib 

            posted @ 2012-03-29 16:48 多彩人生 閱讀(381) | 評(píng)論 (0)編輯 收藏

            stdio.h cstdio

               #include<cstdio>  

            2010-01-26 23:25:29|  分類: 編程 |字號(hào) 訂閱

            在新的C++標(biāo)準(zhǔn)中,生成新頭文件 的方法僅僅是將現(xiàn)有C++頭文件名中的.h去掉。例如,<iostream.h>變成了< iostream>,<complex.h>變成了<complex>,等等。對(duì)于C頭文件,采用同樣的方法,但在每個(gè)名 字前還要添加一個(gè)c。所以C的<string.h>變成了<cstring>,<stdio.h>變成了< cstdio>,等等。    
              舊的C++頭文件是官方所反對(duì)使用的(即,明確列出不再支持),但舊的C頭文件則沒有(以保持對(duì)C的兼容性)。    
              下面是C++頭文件的現(xiàn)狀:    
              ·     舊的C++頭文件名如<iostream.h>將會(huì)繼續(xù)被支持,盡管它們不在官方標(biāo)準(zhǔn)中。這些頭文件的內(nèi)容不在名字空間std中。    
              ·     新的C++頭文件如<iostream>包含的基本功能和對(duì)應(yīng)的舊頭文件相同,但頭文件的內(nèi)容在名字空間std中。(在標(biāo)準(zhǔn)化的過程中,庫(kù)中有些部分的細(xì)節(jié)被修改了,所以舊頭文件和新頭文件中的實(shí)體不一定完全對(duì)應(yīng)。)    
              ·     標(biāo)準(zhǔn)C頭文件如<stdio.h>繼續(xù)被支持。頭文件的內(nèi)容不在std中。    
              ·     具有C庫(kù)功能的新C++頭文件具有如<cstdio>這樣的名字。它們提供的內(nèi)容和相應(yīng)的舊C頭文件相同,只是內(nèi)容在std中。

            如果編譯器同時(shí)支持<iostream>和  
              <iostream.h>   。如果使用了#include  
              <iostream>,   得到的是置于名字空間std下的iostream   庫(kù)的元素;  
              如果使用#include   <iostream.h>,得到的是置于全局空間的同樣的元素。在全  
              局空間獲取元素會(huì)導(dǎo)致名字沖突,而設(shè)計(jì)名字空間的初衷正是用來避免這種名  
              字沖突的發(fā)生.
            #if           _MSC_VER   >   1000  
              #pragma   on
            ce  
              #endif  
               
              #ifndef   _CSTDIO_  
              #define   _CSTDIO_  
              #ifdef   _STD_USING  
                #undef   _STD_USING  
                #include   <stdio.h>  
                #define   _STD_USING  
              #else  
                #include   <stdio.h>  
              #endif   /*   _STD_USING   */  
              #endif   /*   _CSTDIO_   */  
               
              上面就是cstdio的全部?jī)?nèi)容(vc6)  
              好像只是include   <stdio.h>而已!!!

            posted @ 2012-03-29 16:38 多彩人生 閱讀(497) | 評(píng)論 (0)編輯 收藏

            僅列出標(biāo)題
            共25頁: First 17 18 19 20 21 22 23 24 25 

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            留言簿(3)

            隨筆分類

            隨筆檔案

            搜索

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            久久精品国产亚洲AV影院| 品成人欧美大片久久国产欧美...| 国产精品免费久久久久电影网| 性色欲网站人妻丰满中文久久不卡| 亚洲国产成人精品91久久久| 国产精品99久久久久久猫咪| 亚洲国产精品久久久久婷婷老年| 2021久久国自产拍精品| 国内精品久久九九国产精品| 国内精品久久国产大陆| 88久久精品无码一区二区毛片 | 狠狠综合久久AV一区二区三区| 久久精品国产亚洲5555| 久久人人爽人人澡人人高潮AV| 久久精品一区二区三区中文字幕 | 国产成人久久精品区一区二区| 91精品国产综合久久久久久| 国产精品久久久久无码av| 精品九九久久国内精品| 国产国产成人久久精品| 综合久久给合久久狠狠狠97色| 狠狠色丁香婷婷久久综合五月| 狠狠色丁香久久婷婷综合蜜芽五月 | 91精品国产高清久久久久久io| 亚洲国产精品久久久久久| 久久伊人色| 九九久久自然熟的香蕉图片| 99久久免费国产精品| 久久精品中文字幕大胸| 99久久免费国产特黄| 人人狠狠综合久久亚洲| 久久国产亚洲精品无码| 久久久久亚洲爆乳少妇无| 国产A三级久久精品| 亚洲国产精品久久66| 久久综合给久久狠狠97色 | 亚洲午夜久久久影院| 94久久国产乱子伦精品免费| 国产成人综合久久精品红| 青青草国产精品久久| 亚洲精品无码成人片久久|