• <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>
            隨筆 - 181  文章 - 15  trackbacks - 0
            <2008年11月>
            2627282930311
            2345678
            9101112131415
            16171819202122
            23242526272829
            30123456

            常用鏈接

            留言簿(1)

            隨筆分類

            隨筆檔案

            My Tech blog

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            在這一部分之前,書中介紹了基本類型的顯式初始化以及簡單的異常處理.
            基本類型的顯式初始化是比較簡單的.就是說你在定義一個整型變量的時候,有兩種不同的情況:
            int i1;         // undefined value
            int i2 = int(); // initialized with zero

            如果按照前一種,會作"值未定義;如果按照后一種,則自動被初始化為0.這樣也就確保了你的類在初始化的時候有一個確定的初始值.
            至于異常的處理等問題,書中會在后面有比較詳細的描述.這里可以看到比較有意思的一點,就是指定函數拋出的異常類型,這于Java很像:
            void f() throw(bad_alloc);
            下面轉入正題:命名空間.
            有了命名空間,它將會取代函數和類作用于全局,并作為它所統領的那些類和函數的唯一標識存在.這樣可以避免命名沖突情況的出現.正如書中所說:
            Unlike classes, namespaces are open for definitions and extensions in different modules. Thus
            you can use namespaces to define modules, libraries, or components even by using multiple
            files. A namespace defines logical modules instead of physical modules (in UML and other
            modeling notations, a module is also called a package).

            可以像這樣定義一個命名空間:
            namespace MyNameSpace
            {
                
            class MyClass
                {
                    
            private:
                    
            char * _classInfo;
                    
            public:
                    
            char* getClassInfo()
                    {
                        
            return _classInfo;
                    }
                    MyClass(
            const char* info)
                    {
                        _classInfo
            =new char[strlen(info)];
                        strcpy(_classInfo,info);
                    }
                    
            ~MyClass()
                    {
                        
            if(_classInfo)
                        {
                            std::cout
            <<"free classinfo";
                            delete[] _classInfo;
                        }
                    }
                };
                
            void printMyClassInfo(MyClass &instance)
                {
                    std::cout
            <<instance.getClassInfo();
                }
            }
            從上面可以看出,這個命名空間里面包括了一個類和一個函數.類中包含了char*類型的成員變量.函數printMyClassInfo 以一個MyClass類型的引用作為參數.為什么要用引用呢?熟悉c++的人應當很清楚,我是通過實驗才剛剛知道原因.這個原因我將會在后面說明.
            好現在來看一下調用過程,通常的調用過程是這樣的:
            int main()
            {
                MyNameSpace::MyClass instance(
            "MyClass!\n");
                MyNameSpace::printMyClassInfo(instance);
            }
            這沒有任何問題,但有意思的是,還可以這樣調用:
            int main()
            {
                MyNameSpace::MyClass instance(
            "MyClass!\n");
                printMyClassInfo(instance);
            }
            看來c++中在使用一個命名空間的類或者函數的時候,這個命名空間就被"自動"引入了.當尋找函數printMyClassInfo的時候會在當前的上下文中進行尋找的同時,還會到以前用到過的命名空間中去尋找.
            當然,通常情況下我們喜歡這樣做:
            using namespace MyNameSpace; 
            int main()
            {
                MyClass instance(
            "MyClass!\n");
                printMyClassInfo(instance);

            }
            但是并不是在任何情況下都鼓勵using namespace這種做法的.在書中將得比較清楚:
            Note that you should never use a using directive when the context is not clear (such as in header
            files, modules, or libraries). The directive might change the scope of identifiers of a namespace,
            so you might get different behavior than the one expected because you included or used your
            code in another module. In fact, using directives in header files is really bad design.

            上面這段話強調了當上下文并不明確的情況下(比如在一個頭文件,組件或者庫里面),不要使用using這種寫法,這個指令會改變命名空間標識符的作用域,這樣你就有可能引發和你預期不相同的行為,因為你會在另外一個組件中引用你的代碼或使用它.事實上,將using標識符寫在頭文件里面是一種相當不好的設計.
            在這里,我看了一下c++程序設計語言這本書,發現命名空間除了像上面這樣聲明以外,還可以像類一樣這樣來寫:
            在命名空間中這樣定義
            void printMyClassInfo(MyClass &);
            然后在外面寫函數的主體
            void MyNameSpace::printMyClassInfo(MyClass &instance)
            {
                std::cout
            <<instance.getClassInfo();
            }
            好了,寫了這么多,再來看看剛才留下來的那個問題.
            其實很簡單,一個函數如果傳遞的是值,那么就會在內存中產生一個一模一樣的"復本",而那個字符指針也會被復制一次.當傳送的值超過它的作用域的時候 ,就會被釋放掉,而被復制的"本體"在程序運行結束之后,又會被"釋放一次".這樣在運行的時候,它會提示你這樣的錯誤:
            *** glibc detected *** double free or corruption (fasttop): 0x0804a008 ***

            在我們的MyClassl類的析構中,我們有一個輸出,所以這里就輸出了兩次:
            free classinfofree classinfo




            posted on 2007-06-14 22:06 littlegai 閱讀(283) 評論(0)  編輯 收藏 引用 所屬分類: 我的讀書筆記
            2020最新久久久视精品爱 | 久久无码一区二区三区少妇| 日本一区精品久久久久影院| 日本道色综合久久影院| 久久久精品人妻无码专区不卡 | 精品熟女少妇AV免费久久 | 久久国产热这里只有精品| 理论片午午伦夜理片久久 | 一极黄色视频久久网站| 亚洲va久久久噜噜噜久久男同| 亚洲午夜精品久久久久久人妖| 久久婷婷色香五月综合激情| 高清免费久久午夜精品| 久久婷婷色香五月综合激情| 久久99国产精品一区二区| 亚洲国产精品成人AV无码久久综合影院 | 久久国产免费直播| a级毛片无码兔费真人久久| 影音先锋女人AV鲁色资源网久久| 国产成人精品久久综合| 色婷婷综合久久久久中文| 香蕉99久久国产综合精品宅男自 | 色综合色天天久久婷婷基地| 99久久精品免费看国产一区二区三区| 久久中文字幕一区二区| 伊人久久精品无码av一区| 亚洲欧美国产精品专区久久| 国产精品久久久久乳精品爆| 久久精品国产91久久麻豆自制 | 久久久久国产亚洲AV麻豆| 久久精品成人免费网站| 国产精品久久久久久影院| 久久午夜伦鲁片免费无码| 99久久夜色精品国产网站| 少妇无套内谢久久久久| 久久这里的只有是精品23| 色播久久人人爽人人爽人人片aV| 久久久青草青青国产亚洲免观| 亚洲一区二区三区日本久久九| 韩国三级大全久久网站| 久久国产乱子伦免费精品|