• <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
            <2009年2月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            1234567

            常用鏈接

            留言簿(1)

            隨筆分類

            隨筆檔案

            My Tech blog

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

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

            如果按照前一種,會(huì)作"值未定義;如果按照后一種,則自動(dòng)被初始化為0.這樣也就確保了你的類在初始化的時(shí)候有一個(gè)確定的初始值.
            至于異常的處理等問題,書中會(huì)在后面有比較詳細(xì)的描述.這里可以看到比較有意思的一點(diǎn),就是指定函數(shù)拋出的異常類型,這于Java很像:
            void f() throw(bad_alloc);
            下面轉(zhuǎn)入正題:命名空間.
            有了命名空間,它將會(huì)取代函數(shù)和類作用于全局,并作為它所統(tǒng)領(lǐng)的那些類和函數(shù)的唯一標(biāo)識(shí)存在.這樣可以避免命名沖突情況的出現(xiàn).正如書中所說:
            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).

            可以像這樣定義一個(gè)命名空間:
            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();
                }
            }
            從上面可以看出,這個(gè)命名空間里面包括了一個(gè)類和一個(gè)函數(shù).類中包含了char*類型的成員變量.函數(shù)printMyClassInfo 以一個(gè)MyClass類型的引用作為參數(shù).為什么要用引用呢?熟悉c++的人應(yīng)當(dāng)很清楚,我是通過實(shí)驗(yàn)才剛剛知道原因.這個(gè)原因我將會(huì)在后面說明.
            好現(xiàn)在來看一下調(diào)用過程,通常的調(diào)用過程是這樣的:
            int main()
            {
                MyNameSpace::MyClass instance(
            "MyClass!\n");
                MyNameSpace::printMyClassInfo(instance);
            }
            這沒有任何問題,但有意思的是,還可以這樣調(diào)用:
            int main()
            {
                MyNameSpace::MyClass instance(
            "MyClass!\n");
                printMyClassInfo(instance);
            }
            看來c++中在使用一個(gè)命名空間的類或者函數(shù)的時(shí)候,這個(gè)命名空間就被"自動(dòng)"引入了.當(dāng)尋找函數(shù)printMyClassInfo的時(shí)候會(huì)在當(dāng)前的上下文中進(jìn)行尋找的同時(shí),還會(huì)到以前用到過的命名空間中去尋找.
            當(dāng)然,通常情況下我們喜歡這樣做:
            using namespace MyNameSpace; 
            int main()
            {
                MyClass instance(
            "MyClass!\n");
                printMyClassInfo(instance);

            }
            但是并不是在任何情況下都鼓勵(lì)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.

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

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




            posted on 2007-06-14 22:06 littlegai 閱讀(284) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 我的讀書筆記
            久久久噜噜噜久久熟女AA片| 久久亚洲色一区二区三区| 久久久久亚洲国产| 77777亚洲午夜久久多人| 亚洲精品蜜桃久久久久久| 久久SE精品一区二区| 99久久精品影院老鸭窝| 久久精品免费网站网| 色欲久久久天天天综合网| 久久99毛片免费观看不卡| 亚洲а∨天堂久久精品| 国产一区二区三区久久| 久久精品国产清自在天天线| 久久se精品一区二区| 亚洲欧美日韩精品久久亚洲区 | 久久精品国产99国产电影网| 久久99精品国产麻豆不卡| 精品国际久久久久999波多野 | 996久久国产精品线观看| 国产精品伊人久久伊人电影| 久久男人Av资源网站无码软件| 99久久精品国产毛片| 久久精品国内一区二区三区 | 日韩欧美亚洲综合久久影院Ds| 久久精品国产乱子伦| 久久久网中文字幕| 欧美精品一本久久男人的天堂| 久久久无码精品亚洲日韩按摩 | 久久精品综合一区二区三区| 国产成人无码久久久精品一| 久久九九久精品国产免费直播| 久久久WWW成人免费精品| 99精品久久久久久久婷婷| 久久免费精品视频| 久久电影网一区| 91久久精品国产免费直播| 1000部精品久久久久久久久| 亚洲va久久久噜噜噜久久男同| 一级女性全黄久久生活片免费 | 久久精品国产91久久麻豆自制| 2022年国产精品久久久久 |