2010-09-14 2 views
35

Я родом из мира Objective-C и Cocoa, где есть много соглашений, и многие люди скажут, что это делает ваш код красивым! Теперь программирование на C++ Я не могу найти хороший документ, подобный этому для C++.Что такое хорошее соглашение об именах для vars, методов и т. Д. На C++?

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html

Standard C++, вероятно, не что-то вроде выше, но я надеюсь, что смогу придерживаться какой-либо другой SDK или API-интерфейсов (например, от Microsoft (?), И т.д.) конвенций.

Надеюсь, вы можете предоставить мне некоторые ссылки.

+97

Я обещаю сократить всех, кто предлагает венгерский язык. – AShelly

+8

@ Услышьте: прочитайте сообщение Джоэла Шпульского на венгерской нотации, и это может изменить ваше мнение. Я не согласен с ним, но пост, тем не менее, стоит того, что объясняет ОГРОМНОЕ недоразумение по этой схеме. –

+28

Обещаю всем, кто предлагает соглашения Google. – Philipp

ответ

59

Выполняйте все, что хотите, до минимального, согласованного и doesn't break any rules.

Лично я считаю, что стиль Boost проще всего; он соответствует стандартной библиотеке (дает единый взгляд на код) и прост.Я лично лавировать на m и p префиксов членов и параметров, соответственно, что дает:

#ifndef NAMESPACE_NAMES_THEN_PRIMARY_CLASS_OR_FUNCTION_THEN_HPP 
#define NAMESPACE_NAMES_THEN_PRIMARY_CLASS_OR_FUNCTION_THEN_HPP 

#include <boost/headers/go/first> 
#include <boost/in_alphabetical/order> 
#include <then_standard_headers> 
#include <in_alphabetical_order> 

#include "then/any/detail/headers" 
#include "in/alphabetical/order" 
#include "then/any/remaining/headers/in" 
// (you'll never guess) 
#include "alphabetical/order/duh" 

#define NAMESPACE_NAMES_THEN_MACRO_NAME(pMacroNames) ARE_ALL_CAPS 

namespace lowercase_identifers 
{ 
    class separated_by_underscores 
    { 
    public: 
     void because_underscores_are() const 
     { 
      volatile int mostLikeSpaces = 0; // but local names are condensed 

      while (!mostLikeSpaces) 
       single_statements(); // don't need braces 

      for (size_t i = 0; i < 100; ++i) 
      { 
       but_multiple(i); 
       statements_do(); 
      }    
     } 

     const complex_type& value() const 
     { 
      return mValue; // no conflict with value here 
     } 

     void value(const complex_type& pValue) 
     { 
      mValue = pValue ; // or here 
     } 

    protected: 
     // the more public it is, the more important it is, 
     // so order: public on top, then protected then private 

     template <typename Template, typename Parameters> 
     void are_upper_camel_case() 
     { 
      // gman was here     
     } 

    private: 
     complex_type mValue; 
    }; 
} 

#endif 

That. (И как я уже говорил в комментариях, не не принять руководство Стиль Google для вашего кода, если это не что-то, как несущественные, как именования.)

+39

Эй! вы пробираетесь в своем предпочтении в стиле скобки! Лично я предпочитаю иметь фигурные скобки даже для однострочных операторов, легко заглушить отступы (когда люди непреднамеренно редактируют с помощью других настроек вкладки/пространства), а фигурные скобки делают область видимой, поэтому вы не задаетесь вопросом, линия должна была принадлежать блоку или нет ... –

+0

+1: Да, это стиль, который я использую в своих проектах.ВКЛЮЧАЯ предпочтение стиля фигурной скобки;) –

+1

Шахта похожа. Единственная разница. Типы начинаются с буквы верхнего регистра. Все остальное начинается с строчной буквы (просто моя причуда). –

3

Хотя многие люди будут предлагать более или менее строгие варианты Hungarian notation (scary!), Для предложений по именованию я предлагаю вам взглянуть на Google C++ Coding Guidelines. Это может быть не самые популярные соглашения об именах, но, по крайней мере, это довольно полно. Помимо звуковых соглашений об именах, здесь есть некоторые полезные рекомендации, однако многое из этого нужно сделать с помощью соли (например, запрет на исключение и стремление держаться подальше от современного стиля программирования на C++).

Несмотря на то, что мне лично нравится экстремальный стиль нестандартных конвенций STL и Boost;).

+12

Руководящие принципы C++ для кодирования Google ужасны, не принимают их. (Кроме всего прочего, как несущественные, как соглашения об именах.) Руководство по стилю Google является антитезой хорошего современного кода на C++. – GManNickG

+5

@GMan: Я согласен, рекомендации Google предназначены специально для обратной совместимости с их существующей базой кода C (как указано в руководящих принципах). Для нового проекта они являются одной из худших вещей, которые могут произойти. –

+1

@GMan, это то, что я изначально думал тоже, но более тщательное изучение документа заставило меня понять, что он имеет хороший баланс между тем, чтобы оставить какую-то комнату для дыхания профессионалам и (что более важно), не позволяя разработчикам новинок взорваться. Вы не можете рассчитывать на то, что команда хороших современных C++-кодеров в любом месте - и даже один плохой кодер может испортить хорошую кодовую базу без строгих правил ... –

0

не столь краткие, как ссылка вы предоставили: но в следующей главе 14 - 24 может помочь :) хех

ссылка: http://www.amazon.com/Coding-Standards-Rules-Guidelines-Practices/dp/0321113586/ref=sr_1_1?ie=UTF8&s=books&qid=1284443869&sr=8-1-catcorr

+0

Просто пропустил его, и вряд ли что-нибудь о том, чтобы называть там (кроме очевидных_like_dont_do_too_long_and_useless_variable_names ...) –

+0

doooh ... вы правы. Я думал о «структурном» соглашении, а не об именовании, потому что я не пытался понять ваш вопрос и прочесть ссылку, которую вы предоставили. – alien052002

+0

В этой книге рассказывается о элементах стиля программирования, которые помогают улучшить качество кода, а нерелевантные детали, такие как соглашения об именах, суммируются в пункте 0: «Не потеть» («Знать, что не стандартизировать»). Это не поможет, если вы почувствуете необходимость стандартизировать нерелевантные детали. –

3

Для решения широкого вопроса руководств по стилю я предлагаю выбрать один и придерживаясь этого.
Google style guide очень подробный/всеобъемлющий, так что это хороший выбор.

Общей конвенции только для именования:

  • camelCase для всех имен (кроме констант).
  • Начиная с капитала, если это класс.
  • Нижний регистр, если нет.
  • Константы в ALL_CAPS с разделительными работами подчеркивания.
  • Функции могут быть записаны так же, как переменные, camelCase (вы можете сказать, что это функция, потому что после нее требуется ()).
  • И переменные-члены с префиксом m и поэтому будут написаны mCamelCase.

Это действительно зависит от вас или людей, с которыми вы работаете/с университетом, в котором вы учитесь.

Для подробного ознакомления с различными руководствами по стилю/обоснованиями позади них, выйдите Прагматический программист Эндрю Хант и Дэвид Томас.

+7

Подробный не означает, что это хорошо. Как я уже сказал по поводу ответа Корнеля, GSC ужасен. Он работает только для них, потому что у них было огромное количество ранее существовавшего кода C с классом (например, код C++). Современный C++ лучше и противоречит руководству по стилю. – GManNickG

+0

Собственно, ИМХО, Деталь близко к хорошему. Если не GSC, то найдите еще один подробный (это хорошо) и используйте это. Важной вещью является постоянство. И подробное руководство помогает в этом. Итак, если GSC шутит, тогда найдите другого и придерживайтесь его. –

1

Это действительно не имеет значения. Просто убедитесь, что вы назовете свои переменные и функции описательно. Также быть последовательным.

вола хуже, чем видеть такой код:

int anInt;     // Great name for a variable there ... 
int myVar = Func(anInt); // And on this line a great name for a function and myVar 
          // lacks the consistency already, poorly, laid out! 

Edit: Как отметил мой комментатор, который нуждается консистенция будет поддерживаться по всей команде. Как таковой не имеет значения, какой метод вы выбрали, если эта последовательность сохраняется. Однако нет правильного или неправильного метода. У каждой команды, с которой я работал, были разные идеи, и я адаптировался к этим.

+2

Это вопрос. Вы говорите так, как раньше никогда не работали в команде. –

+4

Ну, это НЕ имеет значения до тех пор, пока его описательный и последовательный ... Да в команде, которая означает поддержание этой согласованности по всей команде. Я уточню свой ответ. – Goz

19

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

Так что я буду иметь 2 советов:

  • будут соответствует в рамках проекта
  • не использовать зарезервированные идентификаторы (что-нибудь с двумя символами подчеркивания или, начиная с символом подчеркивания с последующим прописной буквой)

Остальное зависит от вас.

+10

+1 для «быть последовательным»; это самое важное правило партии (и единственное, с чем вы, вероятно, согласитесь, чтобы все согласились). –

+0

+1 зарезервированные идентификаторы, просто потому, что компилятор не использует его сейчас, это не значит, что следующая версия не будет –

1

Существует множество разных правил/соглашений, которые люди используют при кодировании C++. Например, некоторые люди предпочитают разделять слова, используя капиталы (myVar или MyVar), или используя символы подчеркивания (my_var). Как правило, переменные, использующие символы подчеркивания, имеют все строчные буквы (по моему опыту).
Существует также стиль кодирования, называемый венгерский, который, как я полагаю, используется microsoft. Я лично считаю, что это пустая трата времени, но это может оказаться полезным. Это были имена переменных, которым даны короткие префиксы, такие как i или f, для указания типа переменных. Например: int iVarname, char * strVarname.

Принято, что вы заканчиваете имя struct/class с помощью _t, чтобы отличать его от имени переменной. Например .:

class cat_t { 
    ... 
}; 

cat_t myCat; 

Это также общепринято, чтобы добавить аффикс указать указатели, такие как pVariable или variable_p.

В целом, там действительно нет ни одного стандарта, но многие. Выбор, который вы делаете для обозначения ваших переменных, не имеет значения, если он понятен и, прежде всего, последователен. Согласованность, согласованность, КОНСУЛЬТАТИВНОСТЬ! (попробуйте ввести трижды!)

И если все остальное не удается, перейдите по нему в Google.

+3

Именование ** каждого ** класса с окончанием '_t' будет прямо злым ... –

+1

Используется для классы, используемые в качестве типов данных. –

+3

какие классы нет? –

7

Мы следуем принципам, перечисленным на этой странице: C++ Programming Style Guidelines


Я также рекомендую вам прочитать The Elements of C++ Style by Misfeldt et al, что вполне отличная книга по этой теме.

+0

Могу ли я использовать документ, указанный в вашей ПЕРВОЙ ссылке, в качестве основного документа в проекте, который я запускаю? –

+0

@HomunculusReticulli, да конечно. – missingfaktor

+0

Спасибо !, высоко оценили! (должно облегчить жизнь) !. Кстати, есть ли атрибуция, которую я должен сделать в нижней части текста и т. Д.? - если да, то кого я отношу? –

10

Я на самом деле часто использую стиль Java: PascalCase для имен типов, camelCase для функций и переменных, CAPITAL_WORDS для макросов препроцессора. Я предпочитаю это по соглашениям Boost/STL, потому что вам не нужно суффиксные типы с _type. Например.

Size size(); 

вместо

size_type size(); // I don't like suffixes 

Это имеет дополнительное преимущество, что код форматировщик StackOverflow распознает Size как имя типа ;-)

2

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

Одна из лучших практик, с которой я столкнулась, заключалась в использовании форматировщиков кода (астайл и uncrustify - 2 примера). форматирование кода может уничтожить форматирование вашего кода - настроить форматтер и позволить ему выполнять свою работу. серьезно, забыть о ручном форматировании и вникать в практику их использования. они сэкономят массу времени.

Как уже упоминалось, будьте очень описательными с указанием имен. также очень специфичны для определения областей (типы классов/пространства данных/пространства имен/анонимные пространства имен). в общем, мне действительно нравится большая часть обычной письменной формы java - это хорошая ссылка и похожа на C++.

, как для конкретного появления/наименования, это небольшой пример похож на то, что я использую (переменные/аргументы lowerCamel и это свидетельствует лишь часть особенностей языка):

/** MYC_BEGIN_FILE_ID::FD_Directory_nanotimer_FN_nanotimer_hpp_::MYC_BEGIN_FILE_DIR::Directory/nanotimer::MYC_BEGIN_FILE_FILE::nanotimer.hpp::Copyright... */ 
#ifndef FD_Directory_nanotimer_FN_nanotimer_hpp_ 
#define FD_Directory_nanotimer_FN_nanotimer_hpp_ 

/* typical commentary omitted -- comments detail notations/conventions. also, no defines/macros other than header guards */ 

namespace NamespaceName { 

/* types prefixed with 't_' */ 
class t_nanotimer : public t_base_timer { 
    /* private types */ 
    class t_thing { 
     /*...*/ 
    }; 
public: 
    /* public types */ 
    typedef uint64_t t_nanosecond; 

    /* factory initializers -- UpperCamel */ 
    t_nanotimer* WithFloat(const float& arg); 
    /* public/protected class interface -- UpperCamel */ 
    static float Uptime(); 
protected: 
    /* static class data -- UpperCamel -- accessors, if needed, use Get/Set prefix */ 
    static const t_spoke Spoke; 
public: 
    /* enums in interface are labeled as static class data */ 
    enum { Granularity = 4 }; 
public: 
    /* construction/destruction -- always use proper initialization list */ 
    explicit t_nanotimer(t_init); 
    explicit t_nanotimer(const float& arg); 

    virtual ~t_nanotimer(); 

    /* 
     public and protected instance methods -- lowercaseCamel() 
     - booleans prefer is/has 
     - accessors use the form: getVariable() setVariable(). 
     const-correctness is important 
    */ 
    const void* address() const; 
    virtual uint64_t hashCode() const; 
protected: 
    /* interfaces/implementation of base pure virtuals (assume this was pure virtual in t_base_timer) */ 
    virtual bool hasExpired() const; 
private: 
    /* private methods and private static data */ 
    void invalidate(); 
private: 
    /* 
     instance variables 
     - i tend to use underscore suffix, but d_ (for example) is another good alternative 
     - note redundancy in visibility 
    */ 
    t_thing ivar_; 
private: 
    /* prohibited stuff */ 
    explicit t_nanotimer(); 
    explicit t_nanotimer(const int&); 
}; 
} /* << NamespaceName */ 
/* i often add a multiple include else block here, preferring package-style inclusions */  
#endif /* MYC_END_FILE::FD_Directory_nanotimer_FN_nanotimer_hpp_ */ 
+0

Вы определенно любите строчные буквы, D – bluish

+0

@bluish ... и не нравится столкновения :) – justin