C ++编码风格

时间:2013-08-11 10:22:57

标签: c++ coding-style

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

现在我需要为我参与的几个C ++项目选择编码风格。这些项目足够大,每个都会有一些程序员在工作。所以我们需要均衡我们的代码风格。我们也想选择社会可接受的编码风格,所以首先我要告诉我们已经决定拥有什么。我的问题是,如果我们的一些选择不是社会不被接受的,那么其他人通常使用C ++编码风格规则。

所以我们选择的是:

文件命名

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

例如:

VeryImportantClass.h
VeryImportantClass.cpp

命名空间命名

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

例如:

namespace Drinks
{
    namespace AlcoholDrinks
    {

    }
}

命名空间结构

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

示例:

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

//cpp file
namespace CommonStuff
{
    namespace SystemParameters
    {
        bool IfWindows()
        {
            //some stuff...
            return ...;
        }
    }
}

命名的类和结构

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

示例:

class MyClass
{

};

struct MyStruct
{

};

类或结构

在某些情况下,如果我们需要类或结构,很难理解。如果结构只保留一些分组数据 - 它是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;
};

输入名称

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

例如:

typedef std::string String;
typedef std::vector<String> StringVector;

变量类型

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

typedef std::string String;
typedef std::vector<String> StringVector;
typedef unsigned char Byte;
typedef std::vector<Byte> ByteVector;
//etc.

变量命名

以较低的字母开头,每个新单词都有一个大写字母(没有下划线)。

示例:

String messageLicenseExpired = "Your product version is expired, please...";
int importantNumber = 13;

类变量命名

以前缀 m _ 开头,然后单词以较低的字母开头,每个新单词都有一个大写字母(没有下划线)。

示例:

int m_myVariable;
int m_otherVariable;

常量

使用所有带下划线的大写字母。

示例:

const String PRODUCT_NAME = "our product";
const Byte IMPORTANT_NUMBER = 13;

常量或预处理器

如果使用#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

命名的函数和方法

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

例如:

int CalculateSometing (int n);
void ToUpper (String& someStr);

括号

除了初始化之外,大括号应该总是进入新行。

示例:

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

否则

else属于新行,请参见上一个示例。

if statement和braces

即使是ifelse之后的单个代码行也应该被包含在内。

示例:

if (someInt > 100)
{
    someInt = 100;
}
else
{
    someInt /= 2;
}

调用方法

箭头和圆点周围没有空格。

示例:

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

obj.Method();
obj->Method();

头文件

  1. 使用#pragma once代替定义警卫。 (#pragma once不是标准,因此在某些编译器中定义防护是必须的)
  2. 仅限一个班级的一个标题。
  3. 仅用于定义的头文件。执行指令必须在相关的cpp文件中,即使它是getter或setter也是如此。这是因为标题的更改会导致长编译。
  4. 指针和参考文献

    如果可能,请使用引用而不是指针。如果可能传递参数作为参考(对于对象),如果不更改值,则更喜欢传递const引用。

    示例:

    String ToUpper(String str);           //bad
    String ToUpper(String& str);          //better
    String ToUpper(const String& str);    //best
    void ToUpper(String& str);            //also solution
    

    错误处理

    如果函数可能失败,则必须返回booltrue表示成功,false表示失败。对于类方法GetLastError()是必须的。对于可能失败的功能,应通过附加参数返回错误代码,例如: 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;
    };
    

    格式

    1. 对齐使用4个空格或制表符。
    2. 长线缠绕,不再是120行符号。
    3. 自我记录代码

      总是欢迎评论,但最好的选择是为变量和函数命名,以解释所有内容。

      示例:

      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.
      

      &安培;和*位置

      在变量类型之后写&*

      示例:

      String* strPtr;
      String& strRef;
      

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

      随意评论并询问是否有不清楚的事项,为什么我们选择了一些。

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

2 个答案:

答案 0 :(得分:2)

不确定这应该是答案还是评论。我会发布一个答案,以便其他人更容易对此发表评论。

我建议您不要使用缩进命名空间。有些项目可以有很深的 命名空间的嵌套级别,这实际上使代码不可读。

答案 1 :(得分:1)

受尊敬的机构有许多编码标准:

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