code-prettify

2016年10月24日 星期一

C++ Coding Style Guide

Coding Style

第一章:
一、以檔案為最小單位,維持一致的風格
二、以這份風格為目標改進,如果現況不是的話
三、對任何規則有疑慮請提出來討論

第二章:
以 Qt Coding Style 為主,下列例外
一、使用 int* p,不要用 int *p



總結

不要使用例外 (Exceptions)
不要使用 Run Time Type Information (RTTI)
明智的使用 Template,而不只是因為你會
使用 C++ 轉型,不要使用 C 形式的轉型

檔案名稱全小寫 myclass.h or myclass.cpp
(for linux 大小寫敏感,打錯時會找不到,所以一律小寫
Ex: KeepALive.h, Keepalive.h, KeepAlive.h...etc)

類別命名使用峰駝式命名大寫開頭 MyClass
函式命名使用峰駝式命名小寫開頭 myFunction()
變數命名使用峰駝式命名小寫開頭 widthOfBox
私有成員變數命名使用 m_ 開頭 m_widthOfBox
全域變數開頭加上 g 及底線 g_widthOfBox
常數變數使用峰駝式命名大寫開頭 WidthOfBox
列舉 (Enum) 使用峰駝式命名大寫開頭
宣告指標或參考時,在 * 或 & 後面加上空白,不要在前面加上空白

大括號應該 (未決定)

引用 (include) 標頭檔 (header file) 的順序如下
(Names and Order of Includes)
自己的標頭檔 (myclass.h)
專案內的標頭檔 (otherclassinproject.h)
自行開發的工具標頭檔 (mylibary.h)
非標準庫標頭檔 (qt...etc)
近乎標準庫標頭檔 (boost)
標準庫標頭檔 (stl 的 iostream)
系統標題檔

順序的目的是確保自我描述(定義),
每個檔案都應該自行 include 需要的標頭檔。

Ex:
#include <string>
#include "otherclass.h"

可能會發生 otherclass.h 沒有 include <string> 但是編譯成功,
當其它地方使用 otherclass 的時候卻編譯失敗。

函式的參數順序及如何選擇使用指標 (pointers) 或參考 (references)
參數的順序是先輸入後輸出
輸入參數使用 const reference
輸出參數使用 non-const pointer


=== Code Style Tools ===
cpplint - automated checker to make sure a C++ file follows Google's C++ style
guide
https://github.com/google/styleguide/tree/gh-pages/cpplint

vera++ - verification, analysis and transformation of C++ source code
https://bitbucket.org/verateam/vera/wiki/Home

Indent - reformats C and C++ code in a user-defined indent style and coding style
http://www.gnu.org/software/indent/

Artistic Style 2.05 - Automatic Formatter
http://astyle.sourceforge.net/

Uncrustify - Code Beautifier
http://uncrustify.sourceforge.net/

clang - C language family frontend for LLVM
http://clang.llvm.org/

C++ Style Checker Tool (Not Free)
http://www.semanticdesigns.com/Products/StyleChecker/CppStyleChecker.html

=== 資料來源 ===
Google C++ Style Guide
http://google.github.io/styleguide/cppguide.html

不要使用例外 (Exceptions)
如果是新專案的話,一開始就使用例外的好處應該會高於付出的成本,
但是存有專案的話,因為所有會被影響的部份要全面考慮,所以成本過高。

避免使用 Run Time Type Information (RTTI)
避免使用 typeid or dynamic_cast

避免複雜的 Template

使用 C++ 轉型,不要使用 C 形式的轉型
使用 static_cast, const_cast, reinterpret_cast
不要用 y = (int)x; 或 int y = int(x);

類別命名使用峰駝式命名大寫開頭 MyClass
函式命名使用峰駝式命名大寫開頭 MyFunction()
變數命名使用 width_of_box 或 widthofbox
私有成員變數命名最後加上底線 width_of_box_ 或 widthofbox_
全域變數開頭加上 g 及底線 g_width_of_box 或 g_widthofbox
常數變數開頭加上 k 且改用峰駝式命名 kWidthOfBox
列舉 (Enum) 使用峰駝式命名大寫開頭

宣告指標或參考時,在 * 或 & 前面加上一個空白,或者在在後面加上空白,
不要同時在前面都加上空白
char *x; or char* x;
NOT
char * x;

大括號應該在同一行
if (codec) {
} else {
}
class 宣告及函式實作時也不例外
class Foo {
}

Foo::Bar() {
}

引用 (include) 標頭檔 (header file) 的順序如下
(Names and Order of Includes)

自己的標頭檔
C 系統標題檔
C++ 系統標題檔
自行開發的工具標頭檔
專案內的標頭檔

函式的參數順序及如何選擇使用指標 (pointers) 或參考 (references)
參數的順序是先輸入後輸出
輸入參數使用 const reference
輸出參數使用 non-const pointer

在 C 要改變傳入參數只能使用指標,C++ 可以使用參考,
使用參考可以避免程式碼比較醜,像是 (*pval)++,
而且參考不像指標會出現空指標。



Function names in C++: Capitalize or not? [closed]
http://stackoverflow.com/questions/1776291/function-names-in-c-capitalize-or-not
此文很下面的回答中有提到 C++11 開始支援的 Range-based for loop 要求要使用的類別實作 begin() 及 end() 函式,所以函式名稱使用小寫比較適合。

另外一個回答有提到標準函式庫習慣使用 my_function 來命名,例如
<algorithm>
http://www.cplusplus.com/reference/algorithm/




QT Coding Conventions
This is an overview of the high-level coding conventions we use when writing Qt code.
https://wiki.qt.io/Coding_Conventions

Qt Coding Style
This is an overview of the low-level coding conventions we use when writing Qt code.

Qt Creator Coding Rules
https://doc-snapshots.qt.io/qtcreator-extending/coding-style.html

不要使用例外 (Exceptions)
不要使用 Run Time Type Information (RTTI)
明智的使用 Template,而不只是因為你會

類別命名使用峰駝式命名大寫開頭 MyClass
函式命名使用峰駝式命名小寫開頭 myFunction()
變數命名使用峰駝式命名小寫開頭 widthOfBox
私有成員變數命名使用 m_ 開頭 m_widthOfBox
列舉 (Enum) 使用峰駝式命名大寫開頭

宣告指標或參考時,在 * 或 & 前面加上一個空白,不要在後面加上空白
char *x;
NOT
char* x;

大括號應該在同一行
if (codec) {
} else {
}
class 宣告及函式實作時例外
class Foo
{
}
Foo::Bar()
{
}

引用 (include) 標頭檔 (header file) 的順序如下
(Including Headers)
自己的標頭檔
專案內的標頭檔
自行開發的工具標頭檔
Qt 標頭檔
STL 標頭檔
系統標題檔

目的是確保所有的標頭檔包含自己所需要的引用

在公開標頭檔引用 Qt 時候加上完整路徑
#include <QtCore/qwhatever.h>
這在 Mac OS X frameworks 是必須的,而且對於非 qmake 專案非常方便



Bjarne Stroustrup's C++ Style and Technique FAQ

Should I use call-by-value or call-by-reference?
http://www.stroustrup.com/bs_faq2.html#call-by-reference

當你想要改變參數時,使用參考或指標,f(X&) or f(X*)
當你不想改變參數時而且物件很大時,使用常數參考 (const reference),f(const X&)
其它情況,使用傳值(call by value),f(X)

Is ``int* p;'' right or is ``int *p;'' right?
C 程式設計師較常強調 int *p, *p 是一個 int。
C++ 程式設計師較常強調 int* p,p 是一個 int pointer 型別。



The GNU C++ Library
https://gcc.gnu.org/onlinedocs/libstdc++/

The GNU C++ Library - Coding Style
https://gcc.gnu.org/onlinedocs/libstdc++/manual/source_code_style.html

類別命名使用小寫,以底線分段,my_class
函式命名使用小寫,以底線分段,my_function()
變數命名使用兩個底線開頭,__width_of_box
私有變數命名使用 _M_ 開頭,_M_width_of_box
私有函式命名使用 _M_ 開頭,_M_width_of_box()
常數變數使用 _S_ 開頭,_S_widthOfBox
列舉 (Enum) 使用 _S_ 開頭,_S_widthOfBox

宣告指標或參考時,在 * 或 & 後面加上空白,不要在前面加上空白
char* x;
NOT
char *x;

呼叫成員函式時,使用 this 指標,this->foo();


Boost Library Requirements and Guidelines
http://www.boost.org/development/requirements.html
(還沒看過)

GNU Coding Standards
http://www.gnu.org/prep/standards/standards.html
(還沒看過)

GCC Coding Conventions
https://gcc.gnu.org/codingconventions.html
(還沒看過)

Why Google Style Guide for C++ is a deal-breaker
https://www.linkedin.com/pulse/20140503193653-3046051-why-google-style-guide-for-c-is-a-deal-breaker




C/C++ include file order/best practices [closed]
http://stackoverflow.com/questions/2762568/c-c-include-file-order-best-practices

h file corresponding to this cpp file (if applicable)
headers from the same component,
headers from other components,
system headers.


The prototype/interface header for this implementation (ie, the .h/.hh file that corresponds to this .cpp/.cc file).
Other headers from the same project, as needed.
Headers from other non-standard, non-system libraries (eg, Qt, Eigen, etc).
Headers from other "almost-standard" libraries (eg, Boost)
Standard C++ headers (eg, iostream, functional, etc)
Standard C headers (eg, cstdint, dirent.h, etc)




#include "filename" or <filename> ?
"filename" 表示先找專案內的檔案名稱,找不到再找 include 路徑下
<filename> 表示直接找 include 路徑下


#include <filename.h> or <filename> ?
filename.h 跟 filename 是兩個不同的檔案,
filename.h 是 C 的實作,filename 是 C++ 的實作,
在現代 C++ 標準,C 的實作已經改為 cfilename。
另外,沒有副檔名的用法只存在於標準函式庫,一般標頭檔還是有副檔名。



header file is .h / .hh / .hpp

使用 .h / .hh 的分別在於區分 C / CPP
一、C 實作,CPP Warp 時,會有相同的檔案名稱,使用不同的副檔名可以區別。
二、C / CPP 使用不同的 Coding Style 時,工具可以區別

使用 .hpp 是 boost 約定 CPP 的 header file 副檔名 (代替上面的 .hh)

另一種用法,.hpp 是代表此檔案包含完整實作,例如 template,這時候沒有 .cpp 檔案。



When can you omit the file extension in an #include directive?
http://stackoverflow.com/questions/441568/when-can-you-omit-the-file-extension-in-an-include-directive

When to use .hpp files
http://stackoverflow.com/questions/20023610/when-to-use-hpp-files

*.h or *.hpp for your class definitions
http://stackoverflow.com/questions/152555/h-or-hpp-for-your-class-definitions

C++: Reason why using “.hh” as extension for C++ header files [closed]
http://stackoverflow.com/questions/10354321/c-reason-why-using-hh-as-extension-for-c-header-files

Is having C++ header files without extension a good practice?
http://programmers.stackexchange.com/questions/135683/is-having-c-header-files-without-extension-a-good-practice

沒有留言:

張貼留言