쭉 읽어보니.. 너무 많은 듯 하여 요약 시킬 필요성을 느꼇다...
간단하게 요약만 하겠다. 본문(https://google.github.io/styleguide/cppguide.html#Nonstandard_Extensions) 참조할 것
모든 내용이 있는 것은 아니다... 잘 모르겠는 부분 또는 필요없어 보이는 부분은 넘어갔다.
- Header Guard를 할 것. (#pragma once, #ifdef...)
- Template, inline은 Header파일에 선언과 정의를 같이 넣을 것.
- Header파일에는 필요한 Header파일을 모두 include 할 것.
- Header Guard는 Project_Path_File_H 형식으로 만들어야 한다.
foo/src/bar/bar.z 파일의 경우 아래와 같이 작성한다.
#ifndef FOO_BAR_BAZ_H_ #define FOO_BAR_BAZ_H_ ... #endif // FOO_BAR_BAZ_H_
- forward declarations를 사용하지 말자.
#include <iostream> int add(int x, int y); // forward declaration using function prototype int main() { using namespace std; cout << "The sum of 3 and 4 is " << add(3, 4) << endl; return 0; }
int add(int x, int y) { return x + y; }
- inline function 은 함수의 길이가 10줄 이하일 때만 사용하자.
- include의 이름과 순서는 다음과 같이 한다.
공통 헤더, C 라이브러리, C++ 라이브러리, 다른 라이브러리의 Header, 프로젝트의 Header
- namespace는 몇몇 상황을 제외하고 사용하자. (using namespace 는 사용을 자제하자.)
- global 변수는 사용하지말 것, namespace 내부에 Nonmember 변수를 배치할 것, 단순히 static 함수를 그룹화하기 위해 클래스를 사용하지 말 것.
- 지역 변수의 경우 선언과 동시에 초기화를 할 것.
int i; i = f(); // Bad -- initialization separate from declaration.
int j = g(); // Good -- declaration has initialization.
std::vector<int> v; v.push_back(1); // Prefer initializing using brace initialization. v.push_back(2);
std::vector<int> v = {1, 2}; // Good -- v starts initialized.
- smart pointer(unique_ptr, share_ptr) 사용 금지.
- 생성자에서 virtual function 호출을 피하고 실패할 수 있는 초기화를 피할 것.
- 암묵적 형변환을 사용하지 말고 명시적 형변환을 사용하자.
- struct와 class를 분리해서 사용하고, struct는 데이터를 전달하는 passive object에만 사용할 것.
- class의 멤버 정의는 public, protected, private 순서로 정의해야 된다.
- 매개 변수를 이용한 출력보다는 return 값을 이용하자.
- 하나의 함수는 길이가 40줄이 넘지 않게 구현하자.
- RTTI 사용하지 말자.
- 사용해야할 때마다 const를 사용하고, c++11에서는 constexpr이 더 낫다.
- Preprocessor Macros를 Header에 선언하지말자. inline, enum, const 등을 더 사용하자.
- 정수는 0, 실수는 0.0, 포인터는 nullptr, 문자는 '\n'를 사용하자.
- sizeof(type)를 사용할때에는 type은 변수명을 사용하자.
Struct data; memset(&data, 0, sizeof(data));
memset(&data, 0, sizeof(Struct));
- auto를 남발하지말자.
- Lambda
- Use lambda expressions where appropriate, with formatting as described below.
- Prefer explicit captures if the lambda may escape the current scope. For example, instead of:
prefer to write:{ Foo foo; ... executor->Schedule([&] { Frobnicate(foo); }) ... } // BAD! The fact that the lambda makes use of a reference to `foo` and // possibly `this` (if `Frobnicate` is a member function) may not be // apparent on a cursory inspection. If the lambda is invoked after // the function returns, that would be bad, because both `foo` // and the enclosing object could have been destroyed.
{ Foo foo; ... executor->Schedule([&foo] { Frobnicate(foo); }) ... } // BETTER - The compile will fail if `Frobnicate` is a member // function, and it's clearer that `foo` is dangerously captured by // reference.
- 복잡한 Template Metaprogramming은 피하자.
- Boost 라이브러리를 사용할 때에는 승인된 라이브러리만 사용하자.
- 적절한 경우에만 C++11을 사용해야하고, 프로젝트에서 C++11 기능을 사용하기 전에 다른 환경으로의 이식성도 고려해야한다.
- 일반 이름 지정 규칙
이름은 설명이 있어야한다. 약어를 피하자. wikipedia 목록에 있는 약어 정도는 괜찮다.
int price_count_reader; // No abbreviation. int num_errors; // "num" is a widespread convention. int num_dns_connections; // Most people know what "DNS" stands for. int lstm_size; // "LSTM" is a common machine learning abbreviation.
int n; // Meaningless. int nerr; // Ambiguous abbreviation. int n_comp_conns; // Ambiguous abbreviation. int wgc_connections; // Only your group knows what this stands for. int pc_reader; // Lots of things can be abbreviated "pc". int cstmr_id; // Deletes internal letters. FooBarRequestInfo fbri; // Not even a word.
- Type Names
Type names start with a capital letter and have a capital letter for each new word, with no underscores: MyExcitingClass, MyExcitingEnum.
The names of all types — classes, structs, type aliases, enums, and type template parameters — have the same naming convention. Type names should start with a capital letter and have a capital letter for each new word. No underscores. For example:
// classes and structs class UrlTable { ... class UrlTableTester { ... struct UrlTableProperties { ... // typedefs typedef hash_map<UrlTableProperties *, string> PropertiesMap; // using aliases using PropertiesMap = hash_map<UrlTableProperties *, string>; // enums enum UrlTableErrors { ...
- Variable Names
변수의 이름 (함수, 매개 변수 포함) 및 데이터 멤버는 모두 소문자로 시작하며 다너 사이에 밑줄이 있을 수 있다. 클래스의 데이터 멤버 변수에는 마지막에 밑줄을 넣는다.
Common Variable names
For example:
string table_name; // OK - uses underscore. string tablename; // OK - all lowercase.
string tableName; // Bad - mixed case.
클래스
Data members of classes, both static and non-static, are named like ordinary nonmember variables, but with a trailing underscore.
class TableInfo { ... private: string table_name_; // OK - underscore at end. string tablename_; // OK. static Pool<TableInfo>* pool_; // OK. };
구조체
Data members of structs, both static and non-static, are named like ordinary nonmember variables. They do not have the trailing underscores that data members in classes have.
struct UrlTableProperties { string name; int num_entries; static Pool<UrlTableProperties>* pool; };
See Structs vs. Classes for a discussion of when to use a struct versus a class.
Const
Variables declared constexpr or const, and whose value is fixed for the duration of the program, are named with a leading "k" followed by mixed case. Underscores can be used as separators in the rare cases where capitalization cannot be used for separation. For example:
const int kDaysInAWeek = 7; const int kAndroid8_0_0 = 24; // Android 8.0.0
All such variables with static storage duration (i.e. statics and globals, see Storage Duration for details) should be named this way. This convention is optional for variables of other storage classes, e.g. automatic variables, otherwise the usual variable naming rules apply.
함수 이름
Regular functions have mixed case; accessors and mutators may be named like variables.
Ordinarily, functions should start with a capital letter and have a capital letter for each new word.
AddTableEntry() DeleteUrl() OpenFileOrDie()
(The same naming rule applies to class- and namespace-scope constants that are exposed as part of an API and that are intended to look like functions, because the fact that they're objects rather than functions is an unimportant implementation detail.)
Accessors and mutators (get and set functions) may be named like variables. These often correspond to actual member variables, but this is not required. For example, int count()
and void set_count(int count)
.
네임스페이스 이름은 모두 소문자로 한다.
Enumerators
Enumerators (for both scoped and unscoped enums) should be named either like constants or like macros: either kEnumName or ENUM_NAME.Preferably, the individual enumerators should be named like constants. However, it is also acceptable to name them like macros. The enumeration name, UrlTableErrors (and AlternateUrlTableErrors), is a type, and therefore mixed case.
enum UrlTableErrors { kOK = 0, kErrorOutOfMemory, kErrorMalformedInput,};enum AlternateUrlTableErrors { OK = 0, OUT_OF_MEMORY = 1, MALFORMED_INPUT = 2,};
매크로 이름
일반 적으로는 매크로는 사용하지 않아야한다. 하지만 사용해야 한다면 모든 글자는 대문자와 밑줄로 지정해야 한다.
#define ROUND(x) ... #define PI_ROUNDED 3.0
- 주석 // 또는 /* */ 중에서 //을 더 많이 사용하도록 하자.
- 코드 한줄당 80자를 초과하지 말자.
- ASCII 보다는 UTF-8을 사용하자.
- Tab보다는 Spacebar를 사용하자.
- 조건부
Prefer no spaces inside parentheses. The if
and else
keywords belong on separate lines.
There are two acceptable formats for a basic conditional statement. One includes spaces between the parentheses and the condition, and one does not.
The most common form is without spaces. Either is fine, but be consistent. If you are modifying a file, use the format that is already present. If you are writing new code, use the format that the other files in that directory or project use. If in doubt and you have no personal preference, do not add the spaces.
if (condition) { // no spaces inside parentheses ... // 2 space indent. } else if (...) { // The else goes on the same line as the closing brace. ... } else { ... }
If you prefer you may add spaces inside the parentheses:
if ( condition ) { // spaces inside parentheses - rare ... // 2 space indent. } else { // The else goes on the same line as the closing brace. ... }
Note that in all cases you must have a space between the if
and the open parenthesis. You must also have a space between the close parenthesis and the curly brace, if you're using one.
if(condition) { // Bad - space missing after IF. if (condition){ // Bad - space missing before {. if(condition){ // Doubly bad.
if (condition) { // Good - proper space after IF and before {.
Short conditional statements may be written on one line if this enhances readability. You may use this only when the line is brief and the statement does not use the else
clause.
if (x == kFoo) return new Foo(); if (x == kBar) return new Bar();
This is not allowed when the if statement has an else
:
// Not allowed - IF statement on one line when there is an ELSE clause if (x) DoThis(); else DoThat();
In general, curly braces are not required for single-line statements, but they are allowed if you like them; conditional or loop statements with complex conditions or statements may be more readable with curly braces. Some projects require that an if
must always have an accompanying brace.
if (condition) DoSomething(); // 2 space indent. if (condition) { DoSomething(); // 2 space indent. }
However, if one part of an if
-else
statement uses curly braces, the other part must too:
// Not allowed - curly on IF but not ELSE if (condition) { foo; } else bar; // Not allowed - curly on ELSE but not IF if (condition) foo; else { bar; }
// Curly braces around both IF and ELSE required because // one of the clauses used braces. if (condition) { foo; } else { bar; }
'Programming Infomation' 카테고리의 다른 글
Programming Infomation - Windows의 session, station, desktop에 대하여... (0) | 2022.01.21 |
---|---|
Programming Infomation - How To Programming - 201805 (0) | 2018.08.26 |
Programming Infomation - Coding Style (0) | 2018.08.22 |
Programming Infomation - Agile Software Development (0) | 2018.07.17 |