C++ 编码风格

ST3*_*ST3 5 c++ coding-style

不确定我的问题是否适合 StackOverflow 问题的所有规则,但我认为这对未来的用户会有帮助。

现在我需要为我参与的几个 C++ 项目选择编码风格。这些项目足够大,每个项目都会有一些程序员工作。所以我们需要均衡我们的代码风格。此外,我们希望选择社会可以接受的编码风格,所以首先我会告诉我们已经决定采用什么。我的问题是,我们的某些选择是否未被社会接受,以及其他哪些选择通常使用 C++ 编码风格规则。

所以我们选择的是:

文件命名

以大写字母开头,每个新单词都有大写字母(没有下划线,没有空格)。

例如:

VeryImportantClass.h
VeryImportantClass.cpp
Run Code Online (Sandbox Code Playgroud)

命名空间命名

以大写字母开头,每个新单词都有大写字母(没有下划线,没有空格)。对齐也应该适当。

例如:

namespace Drinks
{
    namespace AlcoholDrinks
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

命名空间结构

头文件中只有函数/方法原型,实现在cpp文件中,避免使用using namespace实现文件。

例子:

//header
namespace CommonStuff
{
    namespace SystemParameters
    {
        bool IfWindows();
        //some more stuff...
    }
}

//cpp file
namespace CommonStuff
{
    namespace SystemParameters
    {
        bool IfWindows()
        {
            //some stuff...
            return ...;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

类和结构命名

以大写字母开头,每个新单词都有大写字母(没有下划线,没有空格)。没有类似C 的类前缀或类似S 的结构前缀。我们决定——只是多打字而已。

例子:

class MyClass
{

};

struct MyStruct
{

};
Run Code Online (Sandbox Code Playgroud)

类或结构

在某些情况下,很难理解我们是否需要类或结构。如果结构只保留一些分组数据 - 就是这样struct。如果结构保存数据并且有方法——它就是class。例外的方法是构造函数、析构函数和比较运算符。

例子:

class MyClass
{
public:
    MyClass();
    ~MyClass();
    void SetValue(int value);
    int GetValue();
    void PrintValue();
private:
    int m_value;
};

struct MyStruct
{
    MyStruct();
    ~MyStruct();    
    int value;
};
Run Code Online (Sandbox Code Playgroud)

类型名称

以大写字母开头,每个新单词都有大写字母(无下划线)。

例如:

typedef std::string String;
typedef std::vector<String> StringVector;
Run Code Online (Sandbox Code Playgroud)

变量类型

使用我们自己预定义的类型,我们有:

typedef std::string String;
typedef std::vector<String> StringVector;
typedef unsigned char Byte;
typedef std::vector<Byte> ByteVector;
//etc.
Run Code Online (Sandbox Code Playgroud)

变量命名

每个新单词以小写字母开头,大写字母(无下划线)。

例子:

String messageLicenseExpired = "Your product version is expired, please...";
int importantNumber = 13;
Run Code Online (Sandbox Code Playgroud)

类变量命名

以前缀m_开头,然后单词以小写字母开头,每个新单词都有一个大写字母(无下划线)。

例子:

int m_myVariable;
int m_otherVariable;
Run Code Online (Sandbox Code Playgroud)

常数

使用全部大写并带有下划线。

例子:

const String PRODUCT_NAME = "our product";
const Byte IMPORTANT_NUMBER = 13;
Run Code Online (Sandbox Code Playgroud)

常量或预处理器

#ifdef如果将使用或其他一些方法检查值,则它必须是预处理器定义。否则就是const

例如:

#define FAILURE_FACTOR_FOR_DEBUG 50
const int MAGIC_NUMBER = 5;

//some code...

String newString = someString.substr(MAGIC_NUMBER);

//some code...

//not the best example, but I think it is understandable.
#ifdef _DEBUG
    int someValue = FAILURE_FACTOR_FOR_DEBUG;
#else
    int someValue = 0;
#end
Run Code Online (Sandbox Code Playgroud)

函数和方法命名

以大写字母开头,每个新单词都有大写字母(无下划线)。

例如:

int CalculateSometing (int n);
void ToUpper (String& someStr);
Run Code Online (Sandbox Code Playgroud)

牙套

除初始化外,大括号应始终换行。

例子:

int arr[] = {1, 2, 3};
if (arr[0] > 10)
{
    //do something
}
else
{
    //do something else
}
Run Code Online (Sandbox Code Playgroud)

别的

else属于新行,请参阅前面的示例。

if 语句和大括号

if即使是在或之后的单个代码行也else应该被括起来。

例子:

if (someInt > 100)
{
    someInt = 100;
}
else
{
    someInt /= 2;
}
Run Code Online (Sandbox Code Playgroud)

方法调用

箭头和点周围没有空间。

例子:

Object obj;
Object* oPtr = new Object();

obj.Method();
obj->Method();
Run Code Online (Sandbox Code Playgroud)

头文件

  1. 使用#pragma once而不是定义警卫。(#pragma once不是标准的,所以在某些编译器中必须定义防护)
  2. 一个标题仅用于一类。
  3. 头文件仅用于定义。执行指令必须位于相关cpp文件中,即使它是 getter 或 setter。这是因为头文件的改变会导致编译时间过长。

指针和参考

如果可能的话,使用引用而不是指针。const如果可能将参数作为引用传递(对于对象),如果值不会更改,则更愿意作为引用传递。

例子:

String ToUpper(String str);           //bad
String ToUpper(String& str);          //better
String ToUpper(const String& str);    //best
void ToUpper(String& str);            //also solution
Run Code Online (Sandbox Code Playgroud)

错误处理

如果函数可能失败,它必须返回成功和失败的bool值。对于类来说,方法是必须的。对于可能失败的函数,应通过附加参数返回错误代码,例如我们还决定不在代码中使用异常。truefalseGetLastError()bool Function(int param, int* errorCode = NULL)

类结构

在头文件中,首先是公共方法(位于其顶部的构造函数和析构函数)、受保护方法、受保护变量、私有方法、私有变量。没有公共变量,使用 getter 和 setter。

例子:

class MyClass
{
public:
    MyClass();
    ~MyClass();
    int GetPrivateValue();
    void SetPrivateValue(int value);
    int GetProtectedValue();
    void SetProtectedValue(int value);
protected:
    void SomeMethod();
    int m_protectedValue;
private:
    void SomePrivateMethod();
    int m_privateValue;
};
Run Code Online (Sandbox Code Playgroud)

格式化

  1. 使用 4 个空格或制表符对齐。
  2. 长换行,不再是行而是 120 个符号。

自记录代码

评论总是受欢迎的,但最好的选择是为变量和函数命名,以解释一切。

例子:

void Function (const String& str, const String& str2, StringVector& vect);   //very bad

//This functions tokenize string, str is input string, str2 is delimiters string, vect output
void Function (const String& str, const String& str2, StringVector& vect);    //quite bad

void Tokenize (const String& inputString, const String& delimiters, StringVector& output);    //good, anyway comments using this declaration also welcome.
Run Code Online (Sandbox Code Playgroud)

& 和 * 位置

在变量类型之后写入&和。*

例子:

String* strPtr;
String& strRef;
Run Code Online (Sandbox Code Playgroud)

这是我们决定使用的所有内容,问题是,我们是不是错过了什么?另外,有什么是全球不可接受的吗

如果有不清楚的地方,请随时发表评论并询问我们为什么选择一些。

希望对后来的读者有所帮助。

Ed *_*eal 2

受人尊敬的机构提供了许多编码标准:

这是一个很好的 https://wiki.ucar.edu/download/attachments/25039241/european_space_agency_standards.pdf