• <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>
            隨筆 - 55  文章 - 15  trackbacks - 0
            <2012年5月>
            293012345
            6789101112
            13141516171819
            20212223242526
            272829303112
            3456789

            常用鏈接

            留言簿

            隨筆分類

            隨筆檔案

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            1. 取代#define 進(jìn)行值替代
            2. 修飾指針
            3. 修飾參數(shù)和返回值
            4. 修飾類和類成員變量及類成員函數(shù)


            一、值替代
                  #define只在預(yù)處理器進(jìn)行值替代,并且沒有類型標(biāo)識(shí),出現(xiàn)錯(cuò)誤很難排查。const 提供類型信息,在編譯期可以進(jìn)行類型檢查。編譯器在編譯時(shí)可以通過必要的運(yùn)算把一個(gè)復(fù)雜的常量表達(dá)式簡化,稱為常量折疊。
                   我理解的常量折疊是:編譯器會(huì)把這個(gè)常量放到一個(gè)符號(hào)表中,比如說const int i = 1;符號(hào)表中有一個(gè)符號(hào)i,同時(shí)對應(yīng)了一個(gè)數(shù)值1,此時(shí)是不分配內(nèi)存空間的。如果你強(qiáng)行分配內(nèi)存空間的話也可以。
            const int i = 1;
            int* ip = const_cast<int*>(&i);
            *ip = 2;
            cout <<"i = "<<i ;
            cout <<"*ip = "<< *ip;
            cout <<"*(&i) = "<<*(&i) ;
            // i = 1; 
            //*ip = 2;
            // 
            *(&i) = 1;
            不論你怎么通過內(nèi)存修改i,看起來i有兩個(gè)值,1和2,這貌似就是常量折疊。
            內(nèi)部鏈接問題
              C++中的const是內(nèi)部鏈接,即const僅在被定義過的文件中才是可見的,鏈接時(shí)不能被其他編譯單元看到。在定義時(shí),必須賦一個(gè)初值,不然必須用extern顯式地聲明。
            通常,編譯器是不為const創(chuàng)建存儲(chǔ)空間的,相反把這個(gè)定義保存在它的符號(hào)表中。但是extern強(qiáng)制執(zhí)行了存儲(chǔ)空間的分配,因?yàn)閑xtern表示使用外部鏈接,也就是有幾個(gè)不同的編譯單元可以引用它,所以必須有存儲(chǔ)空間。(這句話我的理解是:每個(gè)編譯單元都有自己的符號(hào)表,其他編譯單元是不能看到其他編譯單元符號(hào)表中的東西的。其他編譯單元如果要引用一個(gè)外部變量,該變量必須是在內(nèi)存中,可以讀取的。所以一定要分配空間。外部鏈接一般是找到相應(yīng)名字的內(nèi)存地址,比如鏈接一個(gè)外部函數(shù),就是找到這個(gè)函數(shù)的內(nèi)存地址)
              通常沒有extern的時(shí)候,不會(huì)分配存儲(chǔ)空間。但是有些結(jié)構(gòu)比較復(fù)雜的const,編譯器還是會(huì)分配空間。因?yàn)?h文件中一般放置的都是不分配空間的代碼,所以cosnt變量默認(rèn)為內(nèi)部鏈接。不然鏈接程序在多個(gè)目標(biāo)文件中看到相同的定義就會(huì)”抱怨“。

            用常量表達(dá)式定義數(shù)組大小
              定義數(shù)組的大小的時(shí)候,必須是常量表達(dá)式,不能為變量,至于為什么。不太清楚,只是編譯器在編譯的時(shí)候給出錯(cuò)誤:期望一個(gè)常量表達(dá)式,不能分配一個(gè)長度是0的數(shù)組,變量是長度未知的。(我的理解是,因?yàn)樽兞渴亲兊模绻o態(tài)地聲明了一個(gè)數(shù)組a[b]因?yàn)椋獯_定,定義的時(shí)候b是1,在之后又被修改為2,那數(shù)組a長度到底應(yīng)該是1呢還是2呢?)
              常量表達(dá)式:
              const int i = 100;// constant
                  const int j = 100 + i;// constant express
                  long addr = (long)&j;// forces storage
                 char buf[j + 10];//right
                 const可以應(yīng)用于集合,但是編譯器不會(huì)把一個(gè)集合保存到符號(hào)表中,所以必須分配內(nèi)存。這種情況下,const意味著‘不能改變的一塊內(nèi)存’,編譯器不需要知道里面存儲(chǔ)的內(nèi)容。如果這樣理解的話,那么編譯器在看到int b = 1;這句話的時(shí)候,也會(huì)想”這是一個(gè)int型的變量,我給他分配2個(gè)字節(jié)就行了,里面是什么,或許要到運(yùn)行的時(shí)候再說了“,所以a[b]的長度就是未知長度了。

            二、const 指針和指向const的指針
              int* u, v;== int*u; int v;
                  因?yàn)椋悖珜︻愋蜋z查非常精細(xì),所以,你可以把一個(gè)非const指針賦給const指針,但是不能把一個(gè)const指針賦給非cosnt指針。同樣也不能把指向const的指針賦給指向非const的指針
            int d = 1;
            const int e = 2;
            int* u = &d;//right;
            int* v = &e;//wrong
            int* w = const_cast<int*>(&e);//right
            int* y = (int*)&e;//right


            考慮下面一句代碼:
            char* cp = "howdy";
            ”howdy"是存放在字符常量區(qū)的,它是個(gè)常量,這個(gè)表達(dá)式返回的是一個(gè)const char*,但是在某些編譯器中是可以通過編譯的。但最好寫成const char* cp = "howdy";修改該字符串?dāng)?shù)組是錯(cuò)誤的。如果想修改它就把它放到一個(gè)數(shù)組中char cp[] = "howdy";為什么呢?
            char cp[] = "abcd";
            cp[1] = '2';
            cout <<cp << endl;
            // legall 

            char *cp = "abcd";
            cp[1] = '2';
            cout << cp << endl;//cause runtime error

            第一種情況:"abcd"是放在字符常量區(qū)的,但是數(shù)組是放在棧上的,現(xiàn)在棧上有5個(gè)字節(jié)的數(shù)組,分別存放了'a','b','c','d''/0',所以你修改它沒問題。第二種:"abcd"是放在字符常量區(qū)的,cp只是一個(gè)指針,指向了這串字符串,想修改它是錯(cuò)誤地。

            臨時(shí)量
              他們也需要存儲(chǔ)空間,并且可以構(gòu)造和銷毀,但是,我們看不到它們,并且自動(dòng)地成為常量。一旦計(jì)算結(jié)束,臨時(shí)變量也會(huì)不復(fù)存在,所以對臨時(shí)變量所做的任何操作都會(huì)丟失。
            傳遞指針和引用的時(shí)候一般都用const修飾。
            值拷貝:
            int i = 1;
            intconst ip = &i;
            int* ip2 = ip;//right;because you can't modify ip by ip2

            const int j = 2;
            int k = j;//right;// you can't modify j by k;

            const int m = 1;
            int* mp = &m;//wrong, you can modify m by mp, but m is a constant

            類中的const
            非static變量在構(gòu)造函數(shù)的初始化列表里定義
            static const 在定義的地方初始化,enum可以實(shí)現(xiàn)static const作用
            class A
            {
              enum {size = 100};
            int i[size];
            };//equal to static const int size = 100;

            const對象
            const A a(1); 必須保證對象的數(shù)據(jù)成員在其聲明周期中不被改變。如何保證?用const成員函數(shù),明確表示不改變成員數(shù)據(jù)。聲明的時(shí)候要用const 定義時(shí)也要用const,不然會(huì)被看作兩個(gè)函數(shù)。
            class X
            {
            int i;
            public:
            int f() const;
            };

            int X::f() const 
            {
             return i;
            }

            按位const和按邏輯const
            按位是指這塊內(nèi)存中的每個(gè)字節(jié)都是不能改變的。
            按邏輯是指,可以在某個(gè)成員函數(shù)中修改成員變量。兩種方法:

            class X
            {
              int i;
            public:
              void f() const;
            }

            void X::f() const
            {
              (const_cast<X*>(this))->i++;//right
            }

            void X::f(const X* this)
            {
               this->i++;//illegal
              (const_cast<X*>(this))->i++;//right
            }

            //////////another method//////////
            class X
            {
              mutable int i;
            public:
              void f() const;
            }

            void X::f() const
            {
              i++;//right
            }
            posted on 2012-05-30 16:12 Dino-Tech 閱讀(164) 評(píng)論(0)  編輯 收藏 引用

            只有注冊用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            国产激情久久久久影院小草| 国产亚洲精久久久久久无码| 久久综合九色综合久99| 日本久久中文字幕| 久久精品中文闷骚内射| 99久久国产热无码精品免费久久久久| 亚洲国产成人久久综合一| 模特私拍国产精品久久| 国产精品青草久久久久婷婷 | 久久精品成人欧美大片| 97精品久久天干天天天按摩| 久久精品中文字幕第23页| 久久久久成人精品无码中文字幕| 99久久国产主播综合精品| 精品国产乱码久久久久久呢| 国内精品久久久久久久久| 久久久久亚洲AV片无码下载蜜桃| 久久精品国产只有精品66 | 久久99精品久久久久久秒播 | 久久99国产精品一区二区| 怡红院日本一道日本久久| 东方aⅴ免费观看久久av| 久久精品无码一区二区app| 久久国产精品99精品国产987| 国产精品久久久久蜜芽| 亚洲国产成人久久综合野外| 国产成人久久777777| 国产精品久久久久久久久鸭| 九九精品99久久久香蕉| 人妻无码精品久久亚瑟影视 | 国产精品无码久久综合| 久久精品国产亚洲AV久| 亚洲伊人久久成综合人影院| 亚洲国产日韩欧美综合久久| 久久精品综合一区二区三区| 99久久精品无码一区二区毛片| 久久国产精品久久精品国产| 久久国产精品77777| 精品久久一区二区| 国产高潮久久免费观看| 热综合一本伊人久久精品|