青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

李帥的博客

軟件開發(fā)愛好者

  C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
  14 隨筆 :: 3 文章 :: 4 評論 :: 0 Trackbacks

一.《Google C++ 編程風格指南》里的觀點

 

     公司在推行編碼規(guī)范,領導提議基本上使用《Google C++ 編程風格指南》。其中《Google C++ 編程風格指南》對于頭文件的包含順序是這樣的:

 

Names and Order of Includes

link ▽Use standard order for readability and to avoid hidden dependencies:C library, C++ library, other libraries' .h, your project's .h.

All of a project's header files should belisted as descendants of the project's source directory without use of UNIXdirectory shortcuts . (the current directory) or .. (the parent directory). Forexample, google-awesome-project/src/base/logging.h should be included as

 

#include "base/logging.h"

In dir/foo.cc or dir/foo_test.cc, whosemain purpose is to implement or test the stuff in dir2/foo2.h, order yourincludes as follows:

 

dir2/foo2.h (preferred location — seedetails below).

C system files.

C++ system files.

Other libraries' .h files.

Your project's .h files.

The preferred ordering reduces hiddendependencies. We want every header file to be compilable on its own. Theeasiest way to achieve this is to make sure that every one of them is the first.h file #included in some .cc.

 

dir/foo.cc and dir2/foo2.h are often in thesame directory (e.g. base/basictypes_test.cc and base/basictypes.h), but can bein different directories too.

 

Within each section it is nice to order theincludes alphabetically.

 

For example, the includes ingoogle-awesome-project/src/foo/internal/fooserver.cc might look like this:

 

  1. <span style="font-size:16px;">  
  2. #include "foo/public/fooserver.h"  // Preferred location.  
  3.   
  4. #include <sys/types.h>  
  5.   
  6. #include <unistd.h>  
  7.   
  8.    
  9.   
  10. #include <hash_map>  
  11.   
  12. #include <vector>  
  13.   
  14.    
  15.   
  16. #include "base/basictypes.h"  
  17.   
  18. #include"base/commandlineflags.h"  
  19.   
  20. #include "foo/public/bar.h"  
  21.   
  22.  </span>  


     在這里我談一下我對上面的理解(如不當,還請諸位同學指正):

1.      為了加強可讀性和避免隱含依賴,應使用下面的順序:C標準庫、C++標準庫、其它庫的頭文件、你自己工程的頭文件。不過這里最先包含的是首選的頭文件,即例如a.cpp文件中應該優(yōu)先包含a.h。首選的頭文件是為了減少隱藏依賴,同時確保頭文件和實現(xiàn)文件是匹配的。具體的例子是:假如你有一個cc文件(linux平臺的cpp文件后綴為cc)是google-awesome-project/src/foo/internal/fooserver.cc,那么它所包含的頭文件的順序如下:

  1. <span style="font-size:16px;">#include "foo/public/fooserver.h"  // Preferred location.  
  2.   
  3. #include <sys/types.h>  
  4. #include <unistd.h>  
  5.   
  6. #include <hash_map>  
  7. #include <vector>  
  8.   
  9. #include "base/basictypes.h"  
  10. #include "base/commandlineflags.h"  
  11. #include "foo/public/bar.h"  
  12.   
  13. </span>  

 

 

2. 在包含頭文件時應該加上頭文件所在工程的文件夾名,即假如你有這樣一個工程base,里面有一個logging.h,那么外部包含這個頭文件應該這樣寫:

#include "base/logging.h",而不是#include "logging.h"

 

   我們看到的是這里《Google C++ 編程風格指南》倡導的原則背后隱藏的目的是:

1. 為了減少隱藏依賴,同時頭文件和其實現(xiàn)文件匹配,應該先包含其首選項(即其對應的頭文件)。

 

2. 除了首選項外,遵循的是從一般到特殊的原則。不過我覺得《Google C++ 編程風格指南》的順序:C標準庫、C++標準庫、其它庫的頭文件、你自己工程的頭文件中漏了最前面的一項:操作系統(tǒng)級別的頭文件,比如上面的例子sys/types.h估計不能歸入C標準庫,而是Linux操作系統(tǒng)提供的SDK吧。因此我覺得更準確的說法應該是:OS SDK .h , C標準庫、C++標準庫、其它庫的頭文件、你自己工程的頭文件。

 

3.之所以要將頭文件所在的工程目錄列出,作用應該是命名空間是一樣的,就是為了區(qū)分不小心造成的文件重名。

 

 

二.《C++編程思想》中的不同觀點

   

    與《Google C++ 編程風格指南》不同的是,《C++編程思想》倡導一種不同的規(guī)則。《C++編程思想》P432提到:

頭文件被包含的順序是從“最特殊到最一般”。這就是,在本地目錄的任何頭文件首先被包含。然后是我們自己的所有“工具”頭文件,隨后是第三方庫頭文件,接著是標準C++庫頭文件和C庫頭文件。

要了解其原因:可以看JohnLakos在《Large ScaleC++ Softwre Design》(注:其中文譯名為《大規(guī)模C++程序設計》)中的一段話:

 

保證.h文件的組成部分不被它自身解析(parse),這可以避免潛在的使用錯誤。因為被自身解析缺乏明確提供的聲明或定義。在.c文件的第一行包含.h 文件能確保所有對于構件的物理界面重要的內部信息塊都在.h中(如果的確是缺少了某些信息塊,一旦編譯這個.c文件時就可以發(fā)現(xiàn)這個問題)。

 

    如果包含頭文件的順序是“從最特殊到最一般”,如果我們的頭文件不被它自己解析。我們將馬上找到它,防止麻煩事情發(fā)生。

 

三.我的試驗

 

    到底哪一種包含順序好呢?我使用VS 2005編一個控制臺測試工程TestInc,里面有幾個文件。

 

MyMath.h的代碼如下:

  1. <span style="font-size:16px;">#pragma once  
  2.   
  3. #pragma once  
  4. double acos(double Num);  
  5. </span>  

MyMath.cpp的代碼如下:

  1. <span style="font-size:16px;">double acos(double Num)  
  2. {  
  3.     return 1.0;  
  4. }  
  5.   
  6. </span>  

TestInc.cpp的代碼如下:

  1. <span style="font-size:16px;">#include "stdafx.h"  
  2. #include "TestInc.h"  
  3. #include <stdio.h>  
  4. #include <math.h>  
  5.   
  6.   
  7. int _tmain(int argc, _TCHAR* argv[])  
  8. {  
  9.     double a = acos(0.5);  
  10.     return 0;  
  11. }  
  12. </span>  

    結果出現(xiàn)錯誤:

1>c:\program files\microsoft visualstudio 8\vc\include\math.h(107) : error C2732: 鏈接規(guī)范與“acos”的早期規(guī)范沖突

1>       c:\program files\microsoft visual studio 8\vc\include\math.h(107) : 參見“acos”的聲明

 

     然后我把TestInc.cpp的頭文件包含順序改為:

  1. <span style="font-size:16px;">#include "stdafx.h"  
  2. #include <stdio.h>  
  3. #include <math.h>  
  4. #include "TestInc.h"  
  5. </span>  

 

    則編譯通過了。在調試運行時main函數(shù)調用還是C標準庫的函數(shù)acos,看來函數(shù)調用的順序是按頭文件的包含順序來的,即我自定義的acos函數(shù)被覆蓋了(如果TestInc.h里包含了內聯(lián)函數(shù),則優(yōu)先調用的是內聯(lián)函數(shù))。

 

     從這個小實驗中我得出如下結論:《Google C++ 編程風格指南》和《C++編程思想》倡導的包含頭文件的順序各有優(yōu)點,《Google C++ 編程風格指南》應該能大量減少隱藏的頭文件依賴,而《C++編程思想》則很容易讓你清楚知道你所定義的接口是否和系統(tǒng)庫及第三方庫發(fā)生沖突。

 

四.頭文件包含中的預編譯功能

 

      在Visual Studio環(huán)境下開發(fā)我們發(fā)現(xiàn)幾乎每個cpp文件都要包含stdafx.h這個文件,而且要把它放在最前面的位置,否則就會出錯。這是為什么呢?

       

      原來Visual Studio采用一種預編譯的機制。要了解預編譯機制,先介紹一下預編譯頭。所謂的預編譯頭就是把一個工程中的那一部分代碼,預先編譯好放在一個文件里(通常是以.pch為擴展名的),這個文件就稱為預編譯頭文件這些預先編譯好的代碼可以是任何的C/C++代碼,甚至是inline的函數(shù),但是必須是穩(wěn)定的,在工程開發(fā)的過程中不會被經(jīng)常改變。如果這些代碼被修改,則需要重新編譯生成預編譯頭文件。注意生成預編譯頭文件是很耗時間的。同時你得注意預編譯頭文件通常很大,通常有6- 7M大。注意及時清理那些沒有用的預編譯頭文件。

 

       也許你會問:現(xiàn)在的編譯器都有Time stamp的功能,編譯器在編譯整個工程的時候,它只會編譯那些經(jīng)過修改的文件,而不會去編譯那些從上次編譯過,到現(xiàn)在沒有被修改過的文件。那么為什么還要預編譯頭文件呢?答案在這里,我們知道編譯器是以文件為單位編譯的,一個文件經(jīng)過修改后,會重新編譯整個文件,當然在這個文件里包含的所有頭文件中的東西(.eg Macro, Preprocessor )都要重新處理一遍。 VC的預編譯頭文件保存的正是這部分信息。以避免每次都要重新處理這些頭文件。

 

       根據(jù)上文介紹,預編譯頭文件的作用當然就是提高便宜速度了,有了它你沒有必要每次都編譯那些不需要經(jīng)常改變的代碼。編譯性能當然就提高了。

 

        要使用預編譯頭,我們必須指定一個頭文件,這個頭文件包含我們不會經(jīng)常改變的代碼和其他的頭文件,然后我們用這個頭文件來生成一個預編譯頭文件(.pch 文件)想必大家都知道StdAfx.h這個文件。很多人都認為這是VC提供的一個“系統(tǒng)級別”的,編譯器帶的一個頭文件。其實不是的,這個文件可以是任何名字的。我們來考察一個典型的由AppWizard生成的MFC Dialog Based 程序的預編譯頭文件。(因為AppWizard會為我們指定好如何使用預編譯頭文件,默認的是StdAfx.h,這是VC起的名字)。我們會發(fā)現(xiàn)這個頭文件里包含了以下的頭文件:

  1. <span style="font-size:16px;">#include <afxwin.h> // MFC core and standard components  
  2. #include <afxext.h> // MFC extensions  
  3. #include <afxdisp.h> // MFC Automation classes  
  4. #include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls  
  5. #include <afxcmn.h>  
  6. </span>  

 

        這些正是使用MFC的必須包含的頭文件,當然我們不太可能在我們的工程中修改這些頭文件的,所以說他們是穩(wěn)定的。

 

        那么我們如何指定它來生成預編譯頭文件。我們知道一個頭文件是不能編譯的。所以我們還需要一個cpp文件來生成.pch 文件。這個文件默認的就是StdAfx.cpp。在這個文件里只有一句代碼就是:#include“Stdafx.h”。原因是理所當然的,我們僅僅是要它能夠編譯而已―――也就是說,要的只是它的.cpp的擴展名。我們可以用/Yc編譯開關來指定StdAfx.cpp來生成一個.pch文件,通過/Fp 編譯開關來指定生成的pch文件的名字。打開project ->Setting->C/C++ 對話框。把Category指向Precompiled Header。在左邊的樹形視圖里選擇整個工程,Project Options(右下角的那個白的地方)可以看到 /Fp “debug/PCH.pch”,這就是指定生成的.pch文件的名字,默認的通常是 <工程名>.pch。然后,在左邊的樹形視圖里選擇 StdAfx.cpp,這時原來的Project Option變成了 Source File Option(原來是工程,現(xiàn)在是一個文件,當然變了)。在這里我們可以看到 /Yc開關,/Yc的作用就是指定這個文件來創(chuàng)建一個Pch文件。/Yc后面的文件名是那個包含了穩(wěn)定代碼的頭文件,一個工程里只能有一個文件的可以有 YC開關。VC就根據(jù)這個選項把 StdAfx.cpp編譯成一個Obj文件和一個PCH文件。

         這樣,我們就設置好了預編譯頭文件。也就是說,我們可以使用預編譯頭功能了。以下是注意事項:

 

1)如果使用了/Yu,就是說使用了預編譯,我們在每個.cpp文件的最開頭,包含你指定產生pch文件的.h文件(默認是stdafx.h)不然就會有問題。如果你沒有包含這個文件,就告訴你Unexpected file end.

 

2)如果你把pch文件不小心丟了,根據(jù)以上的分析,你只要讓編譯器生成一個pch文件就可以了。也就是說把stdafx.cpp(即指定/Yc的那個cpp文件)重新編譯一遍就可以了。    

那么在Linux平臺下有沒有這種預編譯機制呢?如果有,它是怎么實現(xiàn)的呢?Linux平臺下GCC編譯器也實現(xiàn)了預編譯機制的。這里以開源IDE CodeBlocks(CodeBlocks內置了GCC編譯器)的工程為例來說明Linux平臺的實現(xiàn):

 

使用CodeBlocks建一個C++工程,然后新建一個my_pch.h,輸入如下代碼:
  1. <span style="font-size:16px;">/*************************************************************** 
  2.  * Name:      my_pch.h 
  3.  * Purpose:   Header to create Pre-Compiled Header (PCH) 
  4.  * Author:     () 
  5.  * Created:   2010-10-26 
  6.  * Copyright:  () 
  7.  * License: 
  8.  * 使用方法: 項目構建選項-->其他選項-->填入下面兩行 
  9.  -Winvalid-pch 
  10.  -include my_pch.h 
  11.  **************************************************************/  
  12.   
  13. #ifndef MY_PCH_H_INCLUDED  
  14. #define MY_PCH_H_INCLUDED  
  15.   
  16. // put here all your rarely-changing header files  
  17.   
  18. #include <iostream>  
  19. #include <string>  
  20.   
  21. #endif  
  22. </span>  

 然后在項目構建選項-->其他選項-->填入下面兩行  -Winvalid-pch  -include my_pch.h
就可以啟用預編譯文件頭。 然后 main.cpp 就可以不用 include 頭文件了,直接這樣就可以編譯了,
  1. <span style="font-size:16px;">int main()  
  2. {   
  3. using namespace std;  
  4.     cout << "Hello world!" << endl;  
  5.     return 0;  
  6. }  
  7. </span>  

即使在上面的代碼寫上下面一行,其實是不起作用的:

  1. <span style="font-size:16px;">#include <iostream> </span>  

 

參考文獻:

 

1. 編譯器處理相關

http://blog.donews.com/xzwenlan/archive/2004/12/23/211668.aspx

 

2. GoogleC++ Style Guide

http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Names_and_Order_of_Includes

 

3.《C++編程思想》

 

4. VC++的預編譯功能

 

http://www.neu.edu.cn/cxsj/pointchart/c11/VC++%282%29.html

 

posted on 2012-02-23 13:04 李帥 閱讀(438) 評論(0)  編輯 收藏 引用

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


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            免费不卡视频| 亚洲一区二区三区精品在线观看| 久久av一区| 一区二区高清视频在线观看| 国产一区二区在线观看免费| 亚洲免费在线视频一区 二区| 欧美成人午夜| 久久精品视频在线| 亚洲免费网址| 狼狼综合久久久久综合网| 亚洲精品在线免费观看视频| 国产在线播精品第三| 美女脱光内衣内裤视频久久网站| 99热免费精品在线观看| 亚洲黄色尤物视频| 欧美一区二视频在线免费观看| 一本在线高清不卡dvd| 夜色激情一区二区| 日韩一区二区久久| 亚洲综合精品| 久久福利一区| 欧美在线视频免费播放| 一区二区三区福利| 亚洲影院色无极综合| 99re亚洲国产精品| 99国产精品一区| 亚洲欧美日韩国产中文| 久久精品在线| 先锋资源久久| 亚洲二区在线| 亚洲美女色禁图| 亚洲一区二区少妇| 国产乱码精品一区二区三区忘忧草| 欧美日韩一区二区在线| 欧美日韩网址| 亚洲一区二区三区激情| 久久精品91久久香蕉加勒比| 久久精品道一区二区三区| 欧美亚洲视频在线观看| 欧美激情麻豆| 国产三级精品在线不卡| 亚洲小少妇裸体bbw| 美女视频黄 久久| 久久久久久久综合日本| aa亚洲婷婷| 欧美一区二区成人| 麻豆久久精品| 午夜在线精品偷拍| 亚洲第一色中文字幕| 亚洲乱码精品一二三四区日韩在线| 欧美激情久久久久| 国产精品一区二区在线观看网站| 欧美三级特黄| 欧美xart系列高清| 亚洲欧美日韩国产综合在线 | 亚洲精品一区二区三| 亚洲男人影院| 欧美国产日韩亚洲一区| 一本久久综合| 狼人天天伊人久久| 激情综合中文娱乐网| 免费高清在线视频一区·| 国产精品乱子乱xxxx| 日韩午夜在线| 欧美激情麻豆| 欧美日韩在线免费观看| 亚洲精品麻豆| 亚洲乱码久久| 欧美在线三级| 国产欧美日本一区二区三区| 久久精品盗摄| 久久综合久久综合久久| 在线视频你懂得一区| 亚洲精品国产欧美| 国产精品午夜电影| 欧美成人首页| 欧美日韩精品福利| 六月丁香综合| 欧美日本在线看| 亚洲在线成人精品| 欧美一级视频一区二区| 国产欧美日韩伦理| 亚洲欧美在线看| 亚洲人成网站影音先锋播放| 亚洲一品av免费观看| 欧美多人爱爱视频网站| 午夜伦欧美伦电影理论片| 欧美在线看片a免费观看| 国产日韩欧美中文| 久久在线免费视频| 欧美日韩中文字幕在线视频| 久久综合给合| 国产精品三级久久久久久电影| 久久av最新网址| 国产麻豆精品视频| 午夜一区二区三区在线观看| 久久成人精品一区二区三区| 免费在线国产精品| 亚洲第一网站免费视频| 一区二区三区高清在线| 国产精品久久久久一区| 午夜精品三级视频福利| 久久综合网络一区二区| 在线电影院国产精品| 欧美三级乱人伦电影| 欧美在线二区| 99精品国产在热久久下载| 久久成人免费网| 亚洲片区在线| 一区二区三区视频免费在线观看| 亚洲国产高潮在线观看| 欧美激情成人在线视频| 亚洲高清精品中出| 亚洲丶国产丶欧美一区二区三区| 欧美精品成人91久久久久久久| 国产午夜精品在线观看| 欧美成人中文字幕| 国产综合18久久久久久| 亚洲视频在线二区| 亚洲一区二区动漫| 国产欧美日韩激情| 久久久91精品国产| 一区二区三区久久精品| 欧美va天堂| 欧美成人黑人xx视频免费观看| 久久精品在线免费观看| 国产婷婷精品| 欧美精品xxxxbbbb| 亚洲一区二区三区激情| 久久久久久久久一区二区| 亚洲一级高清| 国产精品尤物福利片在线观看| 欧美极品欧美精品欧美视频| 中文国产一区| 卡通动漫国产精品| 在线亚洲美日韩| 欧美激情 亚洲a∨综合| 久久aⅴ国产紧身牛仔裤| 久久久xxx| 欧美成人综合一区| 欧美激情乱人伦| 美日韩精品视频免费看| 午夜精品久久久久99热蜜桃导演| 最新中文字幕一区二区三区| 一区二区三区在线视频免费观看 | 亚洲欧美一区二区视频| 老司机精品导航| 欧美一级在线播放| 亚洲私拍自拍| 亚洲一区二区三区四区五区黄| 99热精品在线观看| 香蕉久久一区二区不卡无毒影院| 久久久99精品免费观看不卡| 蜜臀久久久99精品久久久久久| 最近中文字幕日韩精品| 欧美国产日韩一区二区在线观看 | 欧美色欧美亚洲另类二区 | 蜜臀av在线播放一区二区三区| 亚洲欧美电影在线观看| 欧美在线观看www| 国产女优一区| 欧美一区二区三区视频在线观看| 亚洲精品系列| 在线亚洲精品福利网址导航| 亚洲视频中文| 麻豆视频一区二区| 国产精品乱码| avtt综合网| 亚洲欧洲在线视频| 美日韩精品视频免费看| 欧美成人情趣视频| 日韩亚洲欧美综合| 久久综合九色综合欧美狠狠| 国产一区二区三区精品久久久| 亚洲激情小视频| 久久久亚洲精品一区二区三区| 欧美xxx成人| 欧美亚洲专区| 国产视频不卡| 亚洲色在线视频| 欧美日韩另类国产亚洲欧美一级| 欧美精彩视频一区二区三区| 亚洲高清视频的网址| 亚洲一区二区免费| 欧美激情久久久久| 一本综合久久| 午夜精品一区二区三区电影天堂| 激情六月婷婷久久| 久久精品免费电影| 在线视频日本亚洲性| 欧美紧缚bdsm在线视频| 午夜国产精品视频| 欧美mv日韩mv国产网站app| 国产综合网站| 日韩网站免费观看| 日韩一级二级三级| 亚洲伊人色欲综合网| 欧美日韩在线观看视频| 久久久天天操| 欧美日韩国产系列|