2013-08-11 6 views
2

не уверен, что мой вопрос соответствует всем правилам для вопроса StackOverflow, но я думаю, что это будет полезно для будущих пользователей.C++ стиль кодирования

Теперь мне нужно выбрать стиль кодирования для нескольких проектов на 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. 

Variable именование

Начните с нижней буквой и имеют заглавная буква для каждого нового слова (без подчеркивания).

Пример:

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 или else должна быть приложена.

Пример:

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

Методы называя

Нет места вокруг стрелки и точки.

Пример:

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

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

Header файлы

  1. использовать #pragma once вместо опредиления охранников. (#pragma once не является стандартным, поэтому в некоторых компиляторах необходимо установить защитные ограждения)
  2. Один заголовок только для одного класса.
  3. Заголовочные файлы только для определений. Инструкции по выполнению должны быть связаны с соответствующим файлом cpp, даже если он содержит геттер или сеттер. Это связано с тем, что изменения заголовка приводят к длительной компиляции.

указатели и ссылки

Используйте ссылки вместо указателя, если это возможно. Если возможно, передайте параметр в качестве ссылки (для объектов), предпочитайте передавать в качестве ссылки const, если значение не будет изменено.

Пример:

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

обработки

Если функция может не ошибка, он должен вернуть bool значение true для успеха и false неудачи. Для классов метод GetLastError() является обязательным. Для функции, которая может выйти из строя, код ошибки должен быть возвращен через дополнительный параметр, например. bool Function(int param, int* errorCode = NULL) Также мы решили не использовать исключения в нашем коде.

классовая структура

В файле заголовка первые публичные методы (конструкторы и деструкторы на них сверху), защищенные методы, защищенные переменные, частные методы, частные переменные. Нет общедоступных переменных, используйте геттеры и сеттеры.

Пример:

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 символов.

документирован код

Комментарии всегда приветствуются, но лучший выбор, чтобы дать имя для переменных и функций, что объясняет все.

Пример:

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; 

Это все, что мы решили использовать, вопрос, разве мы не пропустили что-то? Кроме того, есть ли что-нибудь глобально неприемлемо?

Не стесняйтесь комментировать и спрашивать, не ясно ли что-то, почему мы выбрали некоторые.

Надеюсь, это будет полезно для последних читателей.

+5

Я не читал все, но я укажу, что использование капитала первых слева переменных не стандарт. Это делает их трудно отличить от классов. Обычный стандарт - это начало в нижнем регистре, затем camelCase – Dave

+0

Также ваш последний комментарий, я недавно переключился на стиль 'String * ptr'. Нет аргументов против него, если вы никогда не инициализируете несколько переменных в одной строке (что в большинстве случаев я считаю неудачным) – Dave

+4

Что касается обработки ошибок, если вы не против исключений (понятных), используйте их. Нет смысла иметь специальные параметры ошибки и последние методы ошибок, когда улов будет достаточным. – Dave

ответ

2

Не уверен, что это должен быть ответ или комментарий. Я отправлю в качестве ответа, так что другим легче прокомментировать это.

Я не большой поклонник отступающих пространств имен, как вы предлагаете. Некоторые проекты могут иметь довольно глубокие уровни вложенности для пространств имен, что действительно делает код нечитаемым.

+1

Обычно я просто отступаю только в пространстве имен 'detail', и это не имеет короткой длины строки лимит, просто ширина экрана или около того. – chris

Смежные вопросы