Google coding guide

81
C++

Transcript of Google coding guide

Page 1: Google coding guide

C++

Page 2: Google coding guide

http://blog.naver.com/ruvendix

코딩가이드를알아보기전에

개발속도를향상시키고하나의대화수단이된다!

Page 3: Google coding guide

http://blog.naver.com/ruvendix

코딩가이드를알아보기전에

자신만의코딩가이드를만들어도되지만!개발경험이부족하다면이미존재하는코딩가이드를따르자!

적어도 int a; 이런건이제그만두자!

Page 4: Google coding guide

코딩가이드를알아보기전에

구글은실력이뛰어난개발자들이있는기업!

물론코딩가이드에는정답이없다!스스로장단점의기준을잡아서판단해야함!

※모든내용을소개하지는않음※※모든내용은아래에있는사이트를참고! ※

http://jongwook.kim/google-styleguide/trunk/cppguide.xml

Page 5: Google coding guide

http://blog.naver.com/ruvendix

목차

Page 6: Google coding guide

http://blog.naver.com/ruvendix

목차

Page 7: Google coding guide

http://blog.naver.com/ruvendix

#define 방어단일헤더파일도존재하지만!

.cc와 .h는운명공동체!

※ .cc는 UNIX의 C++ 파일※

#pragma once 대신!#define 방어를사용하라!

소스파일을 source(src) 또는 script등폴더를만들어서모으고!소스파일의경로에는그폴더를생략한경로를작성 (즉, 기본폴더는생략)

헤더파일은 include(inc) 또는 header 등으로폴더를만듬!

Page 8: Google coding guide

http://blog.naver.com/ruvendix

전방선언

전방선언보다#include를활용하라!

전방선언을이용하면불필요한 #include를줄일수있으나!실질적인성능개선효과는거의없음!

하지만컴파일타임을줄이는효과는있음!

Page 9: Google coding guide

http://blog.naver.com/ruvendix

인라인함수

함수가 10줄이하면인라인함수로만들어라!하지만과도한인라인함수는프로그램을느리게만들수있음!선택문, 반복문, 가변인자, 가상함수, 재귀함수는인라인불가!어차피인라인함수는컴파일러또는 IDE가알아서판단!

인라인메서드는헤더파일에서처리하되,인라인메서드가많아지면 –inl.h에따로모아라!매크로함수보다는인라인함수를이용!

※ IDE는통합개발환경을뜻함※

Page 10: Google coding guide

http://blog.naver.com/ruvendix

매개변수의순서

매개변수는입력 -> 출력순서!입력매개변수는값을참조만하려는목적!출력매개변수는값을변경시키려는목적!입력은주로일반변수, const참조자이고

출력은주로포인터가됨!

새로운매개변수가추가되어도이순서는지켜야함!하지만자신만의스타일이있다면꼭따를필요는없음!

Page 11: Google coding guide

http://blog.naver.com/ruvendix

포함시키는순서

#include의순서를지키면가독성이향상된다!

Page 12: Google coding guide

http://blog.naver.com/ruvendix

목차

Page 13: Google coding guide

http://blog.naver.com/ruvendix

namespace

C++은 namespace가중요하다!

namespace는주로프로젝트의이름!using namespace std; 이런거금지!

대신 using 선언과 namespace 별명은사용가능!

인라인 namespace 금지!헤더파일에는이름있는 namespace만사용!

Page 14: Google coding guide

http://blog.naver.com/ruvendix

namespace

Page 15: Google coding guide

http://blog.naver.com/ruvendix

중첩클래스

멤버클래스는중첩클래스에서만사용가능!

당연한얘기지만멤버클래스를사용하려면중첩클래스자체를포함해야함!

Page 16: Google coding guide

http://blog.naver.com/ruvendix

전역함수

전역함수대신static을사용하라!정말로전역함수를사용하고싶다면

되도록이면이름없는 namespace를활용하라!

모든파일에서사용할함수가필요하다면루트클래스나 #include를활용하라!

Page 17: Google coding guide

http://blog.naver.com/ruvendix

전역함수

static 메서드활용!

Page 18: Google coding guide

http://blog.naver.com/ruvendix

전역함수

이름없는 namespace 활용!이름없는 namespace는 static처럼작동함!

Page 19: Google coding guide

http://blog.naver.com/ruvendix

전역변수

전역변수대신대신static을사용하라!정말로전역변수를사용하고싶다면

POD를다룰때만사용하라!

※ POD는 Plain Old Data, C 형식의구조체를뜻함※

Page 20: Google coding guide

http://blog.naver.com/ruvendix

지역변수

지역변수는선언과동시에초기화하라!

변수는서로관련이있는것들끼리모아라!반복자는그냥반복문안에서만들어라!

반복문에서생성자와소멸자는한번만호출되도록만들어라!

Page 21: Google coding guide

http://blog.naver.com/ruvendix

목차

Page 22: Google coding guide

http://blog.naver.com/ruvendix

생성자

생성자에서는복잡한초기화를삼가라!

복잡한초기화는 Init() 같은메서드로작업하라!생성자에서가상함수를호출하지마라!생성자를복잡하게만들면디버깅이힘들다!

Page 23: Google coding guide

http://blog.naver.com/ruvendix

초기화

필드(멤버변수)는생성자에서초기화하라!

필드는구성원초기화(멤버이니셜라이저)를이용해서초기화하라!

C++11 이상이라해도되도록이면생성자를이용하라!

Page 24: Google coding guide

http://blog.naver.com/ruvendix

explicit

변환생성자에는무조건explicit을사용하라!

변환생성자는 explicit으로묵시적형변환을막아야함!복사생성자는특별한경우가아니라면 explicit을사용하지마라!

Page 25: Google coding guide

http://blog.naver.com/ruvendix

복사생성자

정말필요할때만복사생성자를사용하라!

복사생성자대신 Copy() 같은함수를만들어라!복사생성자는개념자체가복잡해서가독성이저하될수있음!

STL에서객체를자주입출력할때얕은복사가우려되면이동생성자를이용하라!

Page 26: Google coding guide

http://blog.naver.com/ruvendix

복사생성자

기본복사생성자및기본대입연산자를사용하지않겠다고알리는매크로함수

Page 27: Google coding guide

http://blog.naver.com/ruvendix

생성자위임과상속(C++11 이상)

생성자위임과상속을활용하라!

생성자위임과상속은소스코드를줄이는효과가있다!처음보면좀헷갈리지만익숙해지면편하다!

Page 28: Google coding guide

http://blog.naver.com/ruvendix

생성자위임과상속(C++11 이상)

생성자위임은구성원초기화의소스코드를줄이는효과가있다!

Page 29: Google coding guide

http://blog.naver.com/ruvendix

생성자위임과상속(C++11 이상)

자식클래스만의필드가있다면따로초기화해야한다는단점이있음!

Page 30: Google coding guide

http://blog.naver.com/ruvendix

구조체

단순히정보만필요할때는구조체를활용하라!POD로사용할거라면메서드를정의하면안됨!생성자, 소멸자, 접근메서드정도는가능!

그외의다른기능이필요하다면클래스로만들어라!

Page 31: Google coding guide

http://blog.naver.com/ruvendix

클래스상속

상속은되도록이면public 상속을사용하라!

protected나 private 상속은신중히판단하라!상속될가능성이있는클래스는 virtual로만들어라!가독성을위해가상함수는 virtual을전부다붙여라!

Page 32: Google coding guide

http://blog.naver.com/ruvendix

연산자오버로딩

되도록이면연산자오버로딩은삼가라!

연산자오버로딩은프로그램을더복잡하게만들수있다!비교, 대입등은그냥메서드를따로만들어라!되도록이면함수객체정도로만사용하라!

Page 33: Google coding guide

http://blog.naver.com/ruvendix

접근제어

정보은폐를위해필드는private으로 만들어라!상속관계라면필드를 protected로만들어라!필드는접근메서드(Get, Set)로이용하라!static const필드는 public으로만들어라!

Page 34: Google coding guide

http://blog.naver.com/ruvendix

선언순서

가독성을위해선언순서를지켜라!

Page 35: Google coding guide

http://blog.naver.com/ruvendix

선언순서(C++11 이상포함)

선언순서를지키면가독성이향상된다!

typedefenumstatic 또는 const생성자소멸자메서드필드(static 또는 const제외)

public -> protected -> private

Page 36: Google coding guide

http://blog.naver.com/ruvendix

함수의길이

함수의길이가 40줄이넘어가면나눌수있는지고민하라!

함수의길이가너무길어지면알고리즘파악이힘들다!최대한중복을줄이면서단위작업형태로만들어라!

Page 37: Google coding guide

http://blog.naver.com/ruvendix

목차

Page 38: Google coding guide

http://blog.naver.com/ruvendix

소유권과스마트포인터(C++11 이상)

구글은스마트포인터로std::unique_ptr을사용한다!

std::unique_ptr은동적객체와소유권이 1:1 관계지만…std::move()로소유권이전은가능하다!

std::shared_ptr, std::auto_ptr, scoped_ptr, linked_ptr은사용하지마라!

Page 39: Google coding guide

http://blog.naver.com/ruvendix

목차

Page 40: Google coding guide

http://blog.naver.com/ruvendix

참조자인자

참조자인자는되도록이면const를사용하라!

참조자는실수로원본의값을변경할확률이높다!값을변경할목적이라면포인터를인자로넘겨라!

Page 41: Google coding guide

http://blog.naver.com/ruvendix

r-value참조

r-value참조는std::move()를사용하라!

r-value참조자, std::forward, std::move_iterator,std::move_if_noexcept는사용하지마라!

STL에서동적객체의오버헤드가심할때는이동생성자를이용하라!

Page 42: Google coding guide

http://blog.naver.com/ruvendix

오버로딩

오버로딩은되도록이면생성자에서만사용하라!단순히매개변수만달라진다면그냥템플릿을사용하거나

AddInt(), AddDouble() 이렇게함수를만들어라!오버로딩은함수의기능이완전히달라질때만사용하라!

Page 43: Google coding guide

http://blog.naver.com/ruvendix

기본인자

기본인자는되도록이면무시하라!

기본인자를사용하면오버로딩문제로굉장히복잡해진다!기본인자를이용하고싶으면오버로딩을이용하거나함수를새로만들어라!

가변인자정도는기본인자를사용해도된다!

Page 44: Google coding guide

http://blog.naver.com/ruvendix

가변길이배열

가변길이배열은되도록이면무시하라!

가변길이배열과 alloca()는사용하지마라!정말사용하고싶으면 scoped_ptr, scoped_array를사용하라!

Page 45: Google coding guide

http://blog.naver.com/ruvendix

friend

friend는생각보다정보은폐를파괴하지않는다!

friend를자주사용하면가독성에문제가있는건맞음!하지만의외로장점도많다! 간단한테스트를할때는사용하라!

컨트롤클래스에서도꽤쓸만하다!

Page 46: Google coding guide

http://blog.naver.com/ruvendix

예외처리

C++ 방식의예외처리는되도록이면삼가라!

try throw catch는되도록이면사용하지마라!스택되감기때문에디버깅이더힘들어질수있다!

하지만처음부터 C++ 예외처리를이용하는프로젝트도있으므로프로젝트의방향에따라유연하게적응하라!

Page 47: Google coding guide

http://blog.naver.com/ruvendix

RTTI

RTTI를사용한다는건프로그램이불안정하다는것!

실제로가리키고있는객체를확인한다는건프로그램의설계에문제가있다는뜻!

간단한테스트를할때는사용해도괜찮음!

Page 48: Google coding guide

http://blog.naver.com/ruvendix

형식캐스팅

static_cast를많이사용하라!static_cast는 C의형식캐스팅연산자보다안전하다!

const_cast는 const속성을제거하고싶을때사용하라!dynamic_cast는안전성을확인할때만사용하라!

reinterpret_cast는포인터변환에서사용하라!

Page 49: Google coding guide

http://blog.naver.com/ruvendix

스트림

가독성을위해C언어의입출력을사용하라!

cout과 cin은연산자오버로딩때문에디버깅이힘들어질수있다!C언어의입출력은서식지정자가있기때문에디버깅이쉽다!

iostream만있어도 printf()를이용할수있다!

Page 50: Google coding guide

http://blog.naver.com/ruvendix

증감연산자

반복문에서반복자는전위증감연산자를사용하라!

전위증감연산자가후위증감연산자보다기계어가더짧다!큰차이는없지만전위증감연산자를사용하는쪽으로고려하라!

Page 51: Google coding guide

http://blog.naver.com/ruvendix

const

안전성을위해 const는적극적으로사용하라!

const는귀찮은문제가생길수있지만안전성측면에서는좋다!mutable은쓸만하지만스레드에서문제가생길확률이높다!

Page 52: Google coding guide

http://blog.naver.com/ruvendix

constexpr(C++11 이상)

컴파일타임에상수가필요하다면constexpr을사용하라!

const는런타임에서값이바인딩(고정)되지만constexpr은컴파일타임에서값이바인딩된다!따라서 int num_list[Length()] 이런게가능!

Page 53: Google coding guide

http://blog.naver.com/ruvendix

정수형식

정수는되도록이면int를사용하라!

다른정수형식이필요하다면 stdint.h를이용하라!

되도록이면 unsigned는사용하지마라!for (unsigned int i = foo.Length()-1; i >= 0; --i)

이렇게실수할확률이높다!unsigned는최솟값이 0이라는사실을잊지말자!

Page 54: Google coding guide

http://blog.naver.com/ruvendix

64비트이식성

64비트이식성을가지려면intptr_t를사용하라!intptr_t는 32비트와 64비트일때크기가달라진다!

intptr_t의 unsigned 버전인 size_t를사용하려면 %z 서식지정자를사용하라!

Page 55: Google coding guide

http://blog.naver.com/ruvendix

64비트이식성

intptr_t를 32비트와 64비트에적용하려면inttypes.h를포함해서입력에는 SCNdPTR을, 출력에는 PRIdPTR을이용해야함!

Page 56: Google coding guide

http://blog.naver.com/ruvendix

매크로

매크로함수대신인라인함수를사용하라!

매크로상수는열거형, const로대체할수있다!매크로는 #define 방어에만사용하자!

비주얼스튜디오인경우 _DEBUG와 _NDEBUG 정도는가능하다!

Page 57: Google coding guide

http://blog.naver.com/ruvendix

NULL(C++11 이상포함)

형식에따라적절한NULL을사용하라!정수는 0을, 실수는 0.0으로초기화하라!포인터는 NULL 또는 nullptr로초기화하라!char는 ‘\0’을, 문자열은 “”으로초기화하라!

Page 58: Google coding guide

http://blog.naver.com/ruvendix

sizeof

형식보다는식별자를sizeof에사용하라!식별자는변할가능성이거의없지만형식은언제든지변할가능성이높다!

배열을가리키는포인터인경우 sizeof를사용하지마라!그냥포인터를이용해서배열의크기를구하는함수를따로만들어라!

Page 59: Google coding guide

http://blog.naver.com/ruvendix

auto(C++11 이상)

auto는지역변수로만사용하라!

auto를자주사용하면가독성이저하되지만적절한 auto는소스코드를간결하게만들수있다!전역, namespace, 클래스의필드로는사용하지마라!

auto를이용한중괄호초기화도하지마라!함수의반환형식에도사용하지마라!

Page 60: Google coding guide

http://blog.naver.com/ruvendix

auto(C++11 이상)

auto를 STL에이용하면반복자를쉽게선언할수있다!

Page 61: Google coding guide

http://blog.naver.com/ruvendix

중괄호초기화(C++11 이상포함)

중괄호초기화를적극적으로사용하라!중괄호초기화는소스코드를간결하게만들수있다!

C++11 이상부터는 std::initializer_list를이용한초기화도가능하다!

Page 62: Google coding guide

http://blog.naver.com/ruvendix

중괄호초기화(C++11 이상포함)

C++11 이상부터는중괄호초기화가확장됨!

Page 63: Google coding guide

http://blog.naver.com/ruvendix

람다표현식(C++11 이상)

람다표현식은되도록이면무시하라!

람다표현식을잘사용하면소스코드가간결해질수있다!하지만잘못사용하면소스코드가굉장히복잡해질수있다!

자신이없다면람다표현식, std::function, std::bind를사용하지마라!

Page 64: Google coding guide

http://blog.naver.com/ruvendix

목차

Page 65: Google coding guide

http://blog.naver.com/ruvendix

공통규칙

이름은약자를피하고상세하게작성하라!자주사용되는약자는사용해도괜찮음!

하지만과도한생략은오히려더혼란스럽게만듬!

Page 66: Google coding guide

http://blog.naver.com/ruvendix

파일이름

파일이름은전부소문자로작성하라!파일이름은 _ 또는 –을사용해서단어를구분하라!폴더또는디렉토리이름은일관성만유지하라!

관련이있는파일끼리모아야쉽게파악할수있다!

Page 67: Google coding guide

http://blog.naver.com/ruvendix

형식이름

형식이름은전부대문자로시작하라!

형식이름은대문자로구분하라!예) class TestSimpleClass

클래스, 구조체, typedef, 열거형에적용!

Page 68: Google coding guide

http://blog.naver.com/ruvendix

변수이름

변수이름은전부소문자로작성하라!

변수이름은 _을사용해서구분하라!구조체는이규칙을따른다! 전역변수를쓴다면 g_를붙여라!

예) int apple_count

Page 69: Google coding guide

http://blog.naver.com/ruvendix

상수이름

상수이름은 Konstant의약자인k를접두사로사용하라!상수이름은형식이름처럼대문자로구분하라!

예) const int kMaxStage

※ Konstant는상수라는뜻※

Page 70: Google coding guide

http://blog.naver.com/ruvendix

함수이름

함수이름은전부대문자로시작하라!

함수이름은대문자로구분하라!프로그램이종료되는함수는 OrDie를붙여라!

접근함수인 get(), set()은소문자로만들어서다른함수와구분하라!예) void TestFunction(int argument), get_field(void), ExitOrDie(void)

Page 71: Google coding guide

http://blog.naver.com/ruvendix

namespace이름

namespace 이름은전부소문자로작성하라!namespace 이름은프로젝트이름을사용하라!

Namespace 이름은 _을사용해서구분하라!예) namespace good_project

Page 72: Google coding guide

http://blog.naver.com/ruvendix

열거형이름

열거형이름은전부k를접두사로사용하라!

열거형이름을매크로상수처럼사용하는프로젝트가있다면그냥그프로젝트를따르되, 충돌이발생하면이규칙을적용하라!

열거형이름작성규칙은상수이름과동일하다!예) enum TestEnum { kOneEnum, kTwoEnum }

Page 73: Google coding guide

http://blog.naver.com/ruvendix

매크로이름

매크로이름은전부대문자로작성하라!매크로이름은 _을사용해서구분하라!

예) #define MAX_STAGE 100

Page 74: Google coding guide

http://blog.naver.com/ruvendix

목차

Page 75: Google coding guide

http://blog.naver.com/ruvendix

공통주석

주석은알고리즘및사용법위주로설명하라!

과도한주석은필요없다!

누구나알고있는내용을주석으로작성할필요는없다!예) count++; // count의값이 1증가됩니다.

맞춤법및쉼표, 마침표등을활용하라!

Page 76: Google coding guide

http://blog.naver.com/ruvendix

파일주석

모든파일에머리말을주석으로작성하라!파일주석은저작권, 파일설명순서로설명하라!

더이상사용하지않는함수는 “DEPRECATED”또는 “폐기” 등표시를하라!

Page 77: Google coding guide

http://blog.naver.com/ruvendix

파일주석

이런식으로모든소스파일에주석을작성하라!

Page 78: Google coding guide

http://blog.naver.com/ruvendix

목차

Page 79: Google coding guide

http://blog.naver.com/ruvendix

그외의나머지

소스코드의한줄은80자이내로!

ASCII를사용하라! 다국어가필요하면 UTF-8을사용하라!

탭대신스페이스를사용하라!

Page 80: Google coding guide

http://blog.naver.com/ruvendix

그외의나머지

함수의선언은되도록이면한줄에서끝내라!

한줄이넘어가면보기좋게정리하라!

if가한줄이면 if (true) return;이렇게작성하라!

비어있는반복문은 continue로한줄에표현하라!

while (true) continue

Page 81: Google coding guide

http://blog.naver.com/ruvendix