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

            [翻譯]嵌入式C++編程準(zhǔn)則

               譯自:http://www.caravan.net/ec2plus/guide.html


             

             

             A     代碼從C語(yǔ)言到C++語(yǔ)言的移植

            A1     字符常量

                          注解

                                 C中,字符常量是int類(lèi)型,而在C++中,其類(lèi)型為char.

             

                          示例

                                 I = sizeof(‘a’);

             

            C中,i保存的實(shí)際內(nèi)容是sizeof(int)的計(jì)算結(jié)果值,該值要比1大。而在C++中,i存儲(chǔ)的實(shí)際內(nèi)容是sizeof(char),該值總是為1

                         

                          準(zhǔn)則

            當(dāng)將C代碼移植為C++代碼時(shí),所有對(duì)字符常量的sizeof有依賴關(guān)系的表達(dá)式都要被移除。


             

             

            A2     文件范圍內(nèi)的對(duì)象聲明

                          注解

            C++中,在文件范圍內(nèi),聲明一個(gè)沒(méi)有指定存儲(chǔ)類(lèi)型標(biāo)志符的對(duì)象時(shí),實(shí)際上是定義該對(duì)象為外部鏈接符號(hào)(extern)。如果這個(gè)定義中沒(méi)有初始化表達(dá)式,那么該對(duì)象將被初始化為0。相比較于C來(lái)說(shuō),C++程序中聲明的對(duì)象會(huì)被明確的定義且只定義過(guò)1次。

            而在C中,這將被視為一個(gè)暫時(shí)的定義,這種定義方式在一個(gè)translation unit中允許出現(xiàn)多次。

             

            示例

                      int a;          /* (1) */
                      int a = 10;     /* (2) */

            C中,(1)是一種暫時(shí)性的定義。由于(2)被看作是確切的定義,(1)被看作是只是聲明一個(gè)變量。

            C++中,(1)、(2)都被認(rèn)為是定義式。由于存在(1)、(2)兩個(gè)重復(fù)定義式,因此是一個(gè)錯(cuò)誤。

             

                          準(zhǔn)則

            C++中,如果想在文件范圍內(nèi)僅聲明一個(gè)對(duì)象(而不是定義該對(duì)象),那么該對(duì)象不能擁有初始化表達(dá)式,并且需要使用extern來(lái)修飾。

            聲明于文件范圍內(nèi)的每一個(gè)對(duì)象只能顯式的被定義一次。除了一次聲明外,其余所有聲明都必須具有extern修飾并且沒(méi)有初始化表達(dá)式。


             

             

            A.3   const 類(lèi)型修飾符
                  注解
                 C中,在文件范圍內(nèi),一個(gè)使用const修飾而未指明存儲(chǔ)類(lèi)型的對(duì)象具有外部鏈接屬性。而在C++中,它具有內(nèi)部連接屬性。
             
            示例
                      +- file1 --------------------+
                      |      extern const int n;   |
                      +----------------------------+
                      +- file2 --------------------+
                      |      const int n = 10;     |
                      +----------------------------+
            C中,文件file2中的對(duì)象n具有外部連接屬性,因此,文件file1中對(duì)象n(該對(duì)象同樣具有外部鏈接屬性)可以引用它。在C++中,文件file2中的對(duì)象n具有的屬性是內(nèi)部鏈接的,因此,file1中的對(duì)象n無(wú)法引用到它。
                      
                  準(zhǔn)則
                       使用extern顯示修飾const對(duì)象,使該對(duì)象具有外部鏈接屬性。


             

             

            A.4    void*的轉(zhuǎn)型
                  注解
                      C語(yǔ)言標(biāo)準(zhǔn)允許void*轉(zhuǎn)換為T*T表示任何對(duì)象),而在C++中沒(méi)有這樣的標(biāo)準(zhǔn)。在C++中類(lèi)似的轉(zhuǎn)換需要顯示轉(zhuǎn)換來(lái)完成。
              下面這些C標(biāo)準(zhǔn)庫(kù)函數(shù)都返回void*
                          calloc, malloc, realloc, bsearch, memcpy, memmove,
                          memchr, memset
               C++中,將這些函數(shù)的返回值賦值給一個(gè)非void*的指針時(shí),需要
            顯示轉(zhuǎn)換。
                  示例
                      int* p;
                      p = malloc(10 * sizeof(int));
             
                      C++中,對(duì)指針p的賦值需要顯示的轉(zhuǎn)換,如:
             
                      p = (int *)malloc(10 * sizeof(int));
             
                  準(zhǔn)則
              C++中使用new來(lái)代替callocmallocrealloc(參考A.12);
            忽略memcpy, memmove, 以及memset的返回值(通常這些返回值由函數(shù)的第一個(gè)參數(shù)轉(zhuǎn)換而來(lái));對(duì)于其他所有返回void*函數(shù)(包括標(biāo)準(zhǔn)庫(kù)函數(shù)和用戶自定義函數(shù)),需要使用顯式的轉(zhuǎn)換來(lái)將返回值轉(zhuǎn)換為其他指針類(lèi)型。


             

             

            A.5   枚舉類(lèi)型
                  注解
                       C中的枚舉變量是整型。程序中,枚舉類(lèi)型和整型可以互相轉(zhuǎn)換,而不需要顯式的轉(zhuǎn)換。C程序允許枚舉類(lèi)型對(duì)象進(jìn)行++--運(yùn)算。
                       C++中的枚舉是一種用戶自定義類(lèi)型。C++標(biāo)準(zhǔn)允許枚舉類(lèi)型轉(zhuǎn)換為整型,但從整型轉(zhuǎn)換為枚舉類(lèi)型是非法的。C++程序中還不能將內(nèi)置的++以及符合運(yùn)算符(如+=)作用于枚舉類(lèi)型變量上。
                  示例
                      enum RGB { red, green, blue } rgb;
                      ++rgb;
                     
                     如果表達(dá)式(++rgb)采用內(nèi)置的++運(yùn)算符,那么在C++中這是一個(gè)錯(cuò)誤表達(dá)式。該表達(dá)式的語(yǔ)意相當(dāng)于:
                     rgb = rgb + 1;
                      上面的表達(dá)式在C++中還是錯(cuò)誤的。而像下面這樣,對(duì)枚舉值進(jìn)行顯示的轉(zhuǎn)換就是正確的:
                      rgb = RGB(rgb + 1);
                      最好的解決方法是為枚舉類(lèi)型RGB實(shí)現(xiàn)一個(gè)++運(yùn)算符。
                      RBG &operator++(RGB &x)
                      {
                          return x = RGB(x + 1);
                      }
                    
                  準(zhǔn)則
                 C程序移植為C++程序時(shí),在需要的時(shí)候,要為枚舉類(lèi)型實(shí)現(xiàn)類(lèi)型安全的++--操作符。
             


             

             

            A.6    在轉(zhuǎn)型、參數(shù)聲明、sizeof中定義類(lèi)型
                   注解
                      C中,轉(zhuǎn)型表達(dá)式、參數(shù)聲明以及sizeof表達(dá)式中都可以進(jìn)行類(lèi)
            型聲明,而在C++中則不能。
             
            示例
                      void func(struct TAG { int a; } st)
                      {
                          ...
                      }
                     如上所示,TAG在參數(shù)聲明是被定義。
                    準(zhǔn)則
                      把在參數(shù)中聲明的類(lèi)型的定義式,挪到函數(shù)聲明式作用域開(kāi)始處,或者大于該作用域的某處。
             
                       在轉(zhuǎn)型和sizeof表達(dá)式作用域開(kāi)始處,或者大于該作用域的某處定義類(lèi)型。


             

             

            A.7   忽略局部對(duì)象定義式的控制流程跳轉(zhuǎn)
                    注解
                     C中,gotoswitch語(yǔ)句可以使控制流程跳過(guò)塊作用域內(nèi)的局
            部對(duì)象聲明式,甚至有可能是對(duì)象的初始化式。而在C++中不存在這種跳轉(zhuǎn)。
             
            示例
                      goto LABEL;
                      {
                          int v = 0;
                          ...
                      LABEL:
                          ...
                      }
                       C中,上面的代碼是合法的,它假設(shè)標(biāo)簽LABEL之后的代碼不依賴于整型變量v的初值0。而在C++中,這段代碼總是不能通過(guò)編譯。
                   準(zhǔn)則
                        確保gotoswitch語(yǔ)句沒(méi)有跳過(guò)局部對(duì)象的初始化式。


             

             

            A.8   字符數(shù)組的初始化
                   注解
                      C中,允許使用字符串來(lái)初始化一個(gè)字符數(shù)組。初始化表達(dá)式中,數(shù)組可以比字符串少一個(gè)字符空間(‘\0’字符)。在C++中數(shù)組則必須能完全容納字符串。
                  示例
                      char s[3] = "abc";
                       盡管常量字符串為4個(gè)字符大小,但數(shù)組s的大小為3。這種做法在C中合法,而在C++中非法。
                  準(zhǔn)則
                      為了容納‘\0’,請(qǐng)確保字符數(shù)組大小要比字符串長(zhǎng)度大1。因而,有必要將字符數(shù)組大小指定為字符串長(zhǎng)度+1。(也即:char s[4] = "abc";
                      然而,為了使定義式自適應(yīng)于不同的常量字符串,在定義式中不指定數(shù)組大小不失為一種好方法(即:char s[] = "abc";)。


             

             

            A.9   原型聲明
                   注解
                      C++程序要求在使用函數(shù)之前必須聲明該函數(shù)原型。此外,C++程序會(huì)將函數(shù)聲明式f()解釋為f(void)----不帶參數(shù)的函數(shù)。而在C中,這樣的行為是不確定的。
                  示例
                      extern void func();
                      ....
                      sub();
                      func(0);
                      因?yàn)闆](méi)有sub函數(shù)的聲明,因此調(diào)用該函數(shù)是錯(cuò)誤的。由于聲明式中函數(shù)不帶參數(shù),因此以0為參數(shù)調(diào)用func也是個(gè)錯(cuò)誤。
                  準(zhǔn)則
                      確保被調(diào)用的函數(shù)已經(jīng)被聲明。為了強(qiáng)調(diào)函數(shù)f不帶參數(shù),好的做法是在聲明函數(shù)時(shí),將參數(shù)聲明為void,即聲明式為:f(void).


             

             

            A.10 C++增加的關(guān)鍵字
                 注解
                      C中沒(méi)有下面的C++關(guān)鍵字:
                      asm             bool            catch           class
                      const_cast      delete          dynamic_cast    explicit
                      false           friend          inline          mutable
                      namespace       new             operator        private
                      protected       public          reinterpret_cast
                      static_cast     template        this            throw
                      true            try             typeid          typename
                      using           virtual         wchar_t

            示例

                      int class, new, old;

                     準(zhǔn)則

                               確保沒(méi)有使用C++關(guān)鍵字作為標(biāo)記符。


             

             

            A.11 嵌套類(lèi)型的作用域
                 注解
                      C結(jié)構(gòu)體或聯(lián)合體內(nèi)定義嵌套類(lèi)型,該類(lèi)型的作用域終止點(diǎn)和該結(jié)構(gòu)
            體或聯(lián)合體相同。而C++中定義的嵌套類(lèi)型作用域終結(jié)于該結(jié)構(gòu)或聯(lián)合體。
            示例
                      struct S {
                          int a;
                          struct T {
                              int t;
                          } b;
                          int c;
                          enum E { V1, V2 } e;
                      };
             
                      struct T x;
                      enum E y;
                     xy的聲明在C程序中是合法的,但在C++中非法。在C++程序中,
            在類(lèi)S中定義的類(lèi)型TE的作用域不會(huì)超過(guò)類(lèi)S的定義范圍。
            準(zhǔn)則
                除非只是在結(jié)構(gòu)體或聯(lián)合體內(nèi)使用定義的嵌套類(lèi)型,否則不在嵌套作用域內(nèi)定義類(lèi)型。


             

             

            A.12 動(dòng)態(tài)內(nèi)存管理
                 注解
                      newdeletemallocfree沒(méi)有采用相同的內(nèi)存管理策略。因此,
            除非已經(jīng)使用new獲取了內(nèi)存,否則應(yīng)用程序中不能使用delete來(lái)釋放內(nèi)
            存。同樣,除非使用了malloc分配內(nèi)存,否則不能使用free來(lái)釋放內(nèi)存。
             示例
                      int (*p)[10];
                      p = (int (*)[10])malloc(sizeof(*p));
                      ....
                      delete p;
             
                      這里的delete具有未定義的行為。
                 準(zhǔn)則
                    C++中避免使用malloccallocreallocfree函數(shù),而僅使用
            new/delete.


             

             

            A.13 '/'之后的'/*'
                 注解
                    C++程序具有‘//’的注釋風(fēng)格,因此緊接在符號(hào)‘/’之后的C風(fēng)格
            注釋‘/**/’,會(huì)被C++程序作為理解為‘//’后接‘**/’
            示例
                      i = j //* comment */ k ;
                     //’被解釋為注釋分隔符,因而表達(dá)式被解釋為‘i=j’而不是‘i=j/k’。
            準(zhǔn)則
                盡量避免緊接著符號(hào)‘/’后寫(xiě)C風(fēng)格注釋‘/**/’.

             


             

             

            B.    關(guān)于代碼容量的準(zhǔn)則
            B.1   對(duì)象初始化
                   注解
            有很多方法來(lái)初始化某個(gè)對(duì)象,有些初始化方法將會(huì)產(chǎn)生不必要的
            臨時(shí)對(duì)象,從而導(dǎo)致代碼量膨脹。
                 例如:
                      T x(i)        // (1)
             
                      T x = i;      // (2)
             
                      T x = T(i)    // (3)
             
                      T x;          // (4)
                      x = i;        //
            (1) 直接使用構(gòu)造函數(shù)來(lái)初始化對(duì)象x,這樣就不會(huì)產(chǎn)生臨時(shí)對(duì)象。
            調(diào)用形式類(lèi)似于:
            x.T(i);             // x對(duì)象調(diào)用構(gòu)造函數(shù)
            (2) 在某些實(shí)現(xiàn)中,方法(2)類(lèi)似于方法(1),即對(duì)象x直接調(diào)用
            構(gòu)造函數(shù)。而在另外一些實(shí)現(xiàn)中,該方法會(huì)先使用構(gòu)造函數(shù)生成一個(gè)臨時(shí)對(duì)象,然后將該臨時(shí)對(duì)象作為對(duì)象x的初始值。調(diào)用形式類(lèi)似于:
                          temp.T(i);        // 生成temp
                          x.T(temp);        // x調(diào)用拷貝構(gòu)造函數(shù)
                          temp.~T();        // 析構(gòu)temp
            (3) 等同于(2
            (4) 使用T的默認(rèn)構(gòu)造函數(shù)來(lái)初始化x,然后調(diào)用賦值操作符將新值
            賦給x。賦值操作符可能會(huì)釋放x正在使用的資源,并重新為x獲取新的資源。
                          x.T();           // x調(diào)用默認(rèn)構(gòu)造函數(shù)
                          x.operator=(i); // x調(diào)用賦值操作符
                   準(zhǔn)則
                        在上面的四種方法中,優(yōu)先考慮方法(1)。
             


             

             

            B.2   inline標(biāo)記符
                 注解
                      內(nèi)聯(lián)減少了函數(shù)進(jìn)出棧上的管理開(kāi)銷(xiāo),但這也同時(shí)增加了代碼容量。
                      在內(nèi)內(nèi)部定義的成員函數(shù)默認(rèn)是內(nèi)聯(lián)的。
                 準(zhǔn)則
                      僅對(duì)小函數(shù)進(jìn)行inline修飾。在類(lèi)體之外定義所有不適合作為內(nèi)聯(lián)函數(shù)的成員方法,從而使得該成員不是內(nèi)聯(lián)函數(shù)。


             

             

            B.3   返回值中的臨時(shí)對(duì)象
                 注解
                     函數(shù)按值返回一個(gè)對(duì)象時(shí),可能需要?jiǎng)?chuàng)建并銷(xiāo)毀一個(gè)臨時(shí)對(duì)象,從而
            導(dǎo)致代碼量增加并且?guī)?lái)運(yùn)行時(shí)開(kāi)銷(xiāo)。
             示例
                      class Matrix {
                          int a, b;
                      public:
                          Matrix &operator+=(const Matrix &);
                          friend
                              Matrix operator+(const Matrix &, const Matrix &);
                      };
             
                      Matrix operator +(const Matrix &, const Matrix &)
                      {
                          ...
                      }
             
                      void func()
                      {
                          Matrix a,b;
                          a = a + b;        // (1)
                          a += b;           // (2)
                      }
                      函數(shù)func在(1)處調(diào)用了+操作符,該操作符按值返回一個(gè)Matrix
            對(duì)象。在某些編譯器實(shí)現(xiàn)中,會(huì)先構(gòu)造一個(gè)Maxtrix臨時(shí)對(duì)象,然后銷(xiāo)毀
            該臨時(shí)對(duì)象。
                      函數(shù)func在(2)處調(diào)用+=操作符,該操作符返回一個(gè)Matrix對(duì)象
            引用,因而不會(huì)構(gòu)造臨時(shí)對(duì)象。
                 準(zhǔn)則
                     對(duì)于類(lèi)類(lèi)型對(duì)象,使用復(fù)合賦值操作符(如使用‘+=’而不是‘+’和
            =’)來(lái)避免編譯器生成再銷(xiāo)毀不必要的臨時(shí)對(duì)象。
             
            注:個(gè)人認(rèn)為這個(gè)準(zhǔn)則有失準(zhǔn)確。此例中,+=操作符不產(chǎn)生臨時(shí)對(duì)象的原因在于該操作符按引用返回對(duì)象而非按值返回對(duì)象。因此,準(zhǔn)確的說(shuō)法是,使用按引用或指針?lè)祷貙?duì)象的函數(shù)來(lái)避免構(gòu)造不必要的臨時(shí)對(duì)象。


             

             

            B.4   newdelete操作符
                 準(zhǔn)則
                    在必要時(shí),實(shí)現(xiàn)類(lèi)屬的newdelete操作符,從而提升管理動(dòng)態(tài)內(nèi)存
            的速度和內(nèi)存利用率。


             

             

            B.5   全局對(duì)象的初始化
                 注解
                      全局對(duì)象初始化的順序依賴于編譯器的實(shí)現(xiàn)。但可以肯定的是,在同一個(gè)解釋單元其初始化順序和對(duì)象的聲明順序相同。
                示例
             
                      文件1           文件2             文件3
             
                      int a = f();    int b = f();      int f(void)
                                                        {
                                                            static int a = 0;
                                                            return a++;
                                                        }
                    程序可能將a初始化為0,而b1,或者反過(guò)來(lái)。這依賴于編譯器如何選擇他們的初始化順序。
                     如果將文件2中變量b的聲明移到文件1中,那么兩變量的初始化順序就隨即確定了,即:
                      文件1           文件2             文件3
             
                      int a = f();                      int f(void)
                      int b = f();                      {
                                                            static int a = 0;
                                                            return a++;
                                                        }
                     這種情況下,a要先于b被初始化。
                     避免編寫(xiě)依賴于不同解釋單元內(nèi)全局對(duì)象初始化順序的代碼。


             

             

            C.    關(guān)于速度的準(zhǔn)則
            C.1   元素為類(lèi)對(duì)象的數(shù)組中的newdelete
                 注解
                     聲明元素為類(lèi)對(duì)象的數(shù)組時(shí),編譯器會(huì)為該數(shù)組每一個(gè)元素調(diào)用構(gòu)造
            函數(shù)。在超出該數(shù)組的作用域范圍時(shí),又會(huì)一一調(diào)用每個(gè)元素的析構(gòu)函數(shù)。構(gòu)造/析構(gòu)可能占用超乎想象的時(shí)間,這在實(shí)時(shí)過(guò)程系統(tǒng)中是一個(gè)問(wèn)題。
            準(zhǔn)則
                在對(duì)時(shí)間要求比較高的過(guò)程系統(tǒng)中,避免創(chuàng)建/銷(xiāo)毀大型的元素為類(lèi)對(duì)象的數(shù)組。


             

             

            C.2   循環(huán)體內(nèi)的對(duì)象聲明
            注解
                     如果在循環(huán)體內(nèi)聲明類(lèi)變量,那么在循環(huán)的每次迭代時(shí)都需要構(gòu)造并
            析構(gòu)該對(duì)象。這種構(gòu)造并析構(gòu)帶來(lái)的問(wèn)題就是循環(huán)執(zhí)行速度降低。
            示例
                      for (i = 0; i < 1000; i++)
                      {
                          FOO a;
                          ...
                      }
                 準(zhǔn)則
                    在循環(huán)體外部聲明類(lèi)類(lèi)型變量,而避免在內(nèi)部聲明。


             

             

            D.    編寫(xiě)只讀型代碼準(zhǔn)則
            D.1   ROM中的const對(duì)象
                 注解
                      通常,如果const對(duì)象具有如下一些屬性,則可以存儲(chǔ)在ROM中:
                      -- 具有static存儲(chǔ)時(shí)長(zhǎng)
                      -- 由常量表達(dá)式初始化
                      -- 是一個(gè)PODplain old data)類(lèi)型對(duì)象
                      POD類(lèi)型對(duì)象具有如下屬性:
                      -- 一個(gè)無(wú)屬性(scalar)類(lèi)型(數(shù)字, 枚舉和指針) 
                      -- 類(lèi)/結(jié)構(gòu)/聯(lián)合體中所有數(shù)據(jù)成員都是public訪問(wèn)權(quán)限并且是
            POD類(lèi)型, 同時(shí)類(lèi)中沒(méi)有用戶自定義的構(gòu)造函數(shù)/析構(gòu)函數(shù),沒(méi)有基類(lèi)和虛函數(shù)
                      -- 所有元素都是POD類(lèi)型的數(shù)組
                  示例
                      static const char lang[] = "EC++";
                      class A {
                          int a;
                      public:
                          A();
                          ~A();
                      };
                      const A x;
             
                      'lang'可能存儲(chǔ)于ROM中,而‘x’則不會(huì)。
                  準(zhǔn)則
                      欲將對(duì)象存儲(chǔ)于ROM中,則將對(duì)象聲明為POD類(lèi)型,并使用常量初始化該對(duì)象。


             

             

            NOTE: The form of presentation used here, and several of the specific
            guidelines, were inspired by the excellent book by Thomas Plum and
            Dan Saks, 'C++ Programming Guidelines' (Plum Hall Inc., 1991).

             

            posted on 2009-04-29 14:02 Wealth 閱讀(1844) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): C++Translation

            <2009年4月>
            2930311234
            567891011
            12131415161718
            19202122232425
            262728293012
            3456789

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            留言簿

            隨筆分類(lèi)(8)

            隨筆檔案(8)

            文章分類(lèi)

            Around Web

            CoBlog

            Develop Usage Link

            搜索

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            久久精品国产福利国产琪琪| 久久久91人妻无码精品蜜桃HD| 丰满少妇人妻久久久久久4| 香港aa三级久久三级老师2021国产三级精品三级在| 久久亚洲AV无码精品色午夜麻豆| 国产精品99久久免费观看| 激情综合色综合久久综合| 久久乐国产综合亚洲精品| 久久精品国产久精国产思思| 色婷婷噜噜久久国产精品12p| 久久91精品国产91久久小草| 国产亚洲精品自在久久| yy6080久久| 亚洲精品乱码久久久久久按摩 | 日本道色综合久久影院| 精品久久8x国产免费观看| 99久久综合狠狠综合久久止| 久久婷婷五月综合国产尤物app| 国内精品伊人久久久久777| 久久婷婷五月综合97色直播| 久久久无码一区二区三区| 久久亚洲精精品中文字幕| 亚洲欧美日韩久久精品第一区| 国产精品岛国久久久久| 久久强奷乱码老熟女网站| 国产高潮国产高潮久久久91 | 日本精品一区二区久久久| 狼狼综合久久久久综合网| 国产精品久久婷婷六月丁香| 久久国产精品免费一区二区三区| 麻豆精品久久精品色综合| 精品久久人妻av中文字幕| 99精品久久久久久久婷婷| 中文字幕久久亚洲一区| 性高朝久久久久久久久久| 久久精品国产亚洲精品| 久久久久久极精品久久久| 精品视频久久久久| 久久久久一本毛久久久| 亚洲精品久久久www| 亚洲精品无码久久久久久|