3. 서론
코딩 컨벤션란?
▸프로그래밍 언어에서 선호되는 프로그래밍 작성 스타일의 협약.
주석, 변수명 작성법 뿐 아니라 프로그래밍 규칙 등 소프트웨어
설계의 기본이됨.
▸코딩 컨벤션의 장점
▸코드의 공정화 (ex. goto )
▸가독성을 늘릴 수 있음 (작성자 보다 읽는 사람이 더 수월하게)
▸코드의 위험한 설계를 피할 수 있음
▸주의!! => 구글 C++ Style Guide가 모든 회사에서 쓰이는 것은 아닙니
다.
각 회사 가셔서 코딩 컨벤션을 준수하세요
5. 헤더(HEADER)
전방 선언
▸ .h파일에 #include 된 불필요한 수정 된 다른 .h파일도 다시 컴파일 되어 컴파일 시간 증가
전방선언을 통해 컴파일 타임이 늘어나는 것을 줄일 수 있음.
▸ 템플릿 클래스 사용할 때 헤더파일에 include를 사용하는걸 선호해라.
(전방 선언의 정확한 형태를 결정하기 힘듬 <= 템플릿은 값전달이기 때문에)
▸ 암시적 변환이 있을 때, 전방 선언을 조심히 해라.
▸ STL 전방 선언하지마라. <= 템플릿이니까, 변경도 적고(STL 수정하지 않는 이상은)
base.hpp
app.hpp app.cpp
6. 헤더(HEADER)
Inline functions
▸ Inline 함수는 10줄 이하로 작성해야 성능 적 이점을 받을 수 있음.
▸ Inline Function에서 소멸자를 호출 주의하라.(소멸자가 함축적으로
상위 클래스와 멤버 변수 소멸자 부르기 때문)
▸ 반복문 및 switch Inline 하는것은 효과적이지 않음.
HEADER에 내용이 많다면 INL로 분리해주자
7. 헤더(HEADER)
Include 순서
▸ 아마 혼자 공부 ,개발 연습 해왔다면 헤더 파일 포함 시킬 때
의식의 흐름대로 추가했을 거다 << (본인 이야기)
▸ Include 순서 C 시스템 파일, C++ 시스템 파일, 다른 프로젝트
헤더파일, 현재 프로젝트 헤더파일
▸ 가능하면 알파벳 순서
8. 범위(SCOPING)
NameSpace
▸ 네임스페이스는 전체 영역(전역)을 구획화하여 이름이 부여된 범위
로 분할하는데, 이는 전체 영역(전역)에서의 이름 충돌을 막는 데 유
용하다.
▸ 네임스페이스 영역이 끝나는 곳에 주석으로 표시해주자.
▸ 네임스페이스는 소문자로 작성하고 프로젝트에 기반한 경로이름을
지어주자
9. 범위(SCOPING)
Unnamed Namespaces && Static Variables
▸ Cpp 파일에서 해당 영역에서만 사용하는 전역 변수 사용시
Unnamed Namespace 또는 Static Variable를 쓰는것을 권장.
이름 충돌을 막을 수 있음.
▸ H 파일에서는 쓰지마세요. Unnamed Namespace와 Static Variable
충돌이 납니다.
A.cpp B.cpp
case 1
case 2
+
A.h B.h
+
10. 범위(SCOPING)
Inline Namespaces
▸ Inline NameSpace를 이용하여 기존 코드를 유지하며 유지보수
할 수 있는 코드를 만들 수 있음.
▸ Inline Namespace 사용 시 네임스페이스 영역의 혼란을 줄수 있으니
남발 금지 ( ex. outer_Socket::Innver_Ver2::Socket ==
outer_Socket::Socket)
11. 범위(SCOPING)
using 지시자
▸ 한 네임스페이스 모든 이름을 활용하기 위한 Using 지시자 사용 하
지마라.
▸ Cpp 파일에서는 원하는 곳에서 사용 가능하나, h 파일에서는 함수
및
클래스 안에서만 사용해야함.
16. 클래스(CLASS)
클래스 생성자
▸ 생성자에서 복잡한 초기화 작업을 하는 것을 피하라
(특히 실패할 수 있는 초기화나 가상 메서드 호출이 필요한 초기화).
▸ 클래스 생성 후 init(), 팩토리 함수를 통해
17. 클래스(CLASS)
explicit 생성자
▸ 인자가 한개인 생성자에 explicit 키워드를 안 쓰면,
사용자가 잘못 사용할 수도 있고, 변환 객체 생성이 된다.
explicit를 통해 생성자가 호출이 안되게 해줘야한다.
18. 클래스(CLASS)
복사 생성자, 복사 대입 연산자
▸ C++ 클래스에서 디폴트로 생성해주는 복사 생성자, 복사 대입 연산
자
를 조심해야함. 복사가 필요하면 꼭 정의를 해주자.
▸ 필요없는 경우 NonCopyable 클래스 상속 하거나, 복사 생성자와
복사 대입 연산자를 private로 선언해준다.
19. 클래스(CLASS)
생성자위임
▸ 상속 클래스가 생성자에서 기본 클래스 생성자와 같은 일을 하고 있
다면
생성자 위임을 통해 코드 중복을 피할 수 있음.
▸ 상속 클래스의 생성자 변경 필요할 경우, 생성자 위임 X
(이런게 있다고만 알아두는게 좋을듯…)
20. 클래스(CLASS)
다중 상속
▸ 다중 상속은 상속 클래스가 복잡해 질 수 있으므로 지양,
다중 상속 필요시 순수한 인터페이스 클래스만 상속하자.
▸ 인터페이스 사용시 Interface를 나타내는 접두사,접미어를
붙이자.
21. 클래스(CLASS)
인터페이스
▸ 인터페이스 클래스는 순수 가상 메서드를 정의해야한다.
생성자를 정의 X, 필요시 인자가 없고 protected로 하자.
클래스 이름의 interface를 명시해주자.
인터페이스를 직접 인스턴스화 하지말자.
22. 클래스(CLASS)
연산자 오버로드
▸ 연산자 오버로드는 직관적으로 만들 수 있음.
▸ 연산자 오버로드 된 곳을 찾기 어려울 수 있으니,
비교 연산자는 함수를 정의해서 쓰는게 바람직.
▸ 대입 연산자= 클래스 자신이 대입하는 경우가 있으니 조심.
주소값, Swap(복사후 맞바꾸기)로 안전하게 진행해주자.
23. 클래스(CLASS)
클래스 선언순서
▸ 클래스 접근 제어 순서는
public -> protected -> private 순으로 작성.
▸ typedef & 열거형 -> 상수 -> 생성자 -> 소멸자 -> 메서드
-> 데이터 멤버 순으로 작성.
24. 레퍼런스&(REFERENCE)
레퍼런스, 포인터
▸ 입력은 레퍼런스, 출력은 포인터로 하는걸 권장.
▸ 레퍼런스 사용함으로 입력값이 nullptr인 것을 피할 수 있고.
함수안에서 실제 변수처럼 사용 가능.
▸ 입력 값을 포인터, 레퍼런스 등으로 저장해야한다면.
pointer값을 입력으로 사용가능.
25. 디폴트 인자 함수
디폴트 인자함수
▸ 처음 정의할 때 디폴트 인자를 가진 함수는 지양하자.
▸ 코드 변경시 사이트 이펙트를 피하기 위해
기존 코드는 디폴트인자를 사용하게 하여 유지하고.
필요한 코드에서 인자값을 넣어서 사용해주자.
26. 전처리기 지시자 포맷팅
전처리기 지시자
▸ # 기호가 항상 그줄 처음에 있게 작성
▸ endif 같은 경우 // comment 작성해주는게 보기 더 수월할거같음.
27. 예외처리(EXCEPTION THORW)
예외 처리
▸ 예외 처리를 위해 try ~ catch 는 사용 않는다.
가장 가까운 catch 문을 찾기 위해 stack unwinding 하는 성능 문제.
try~catch문은 if~else문 보다 느림.
▸ 예외 처리 코드는 if문으로 작성하여 예외가 나지 않게 작성한다.
28. 이름 규칙(NAMING)
일반적인 이름 규칙
▸ 네이밍으로 인해 코드를 읽는게 수월할 수도 있고 지옥이 될수도 있
음.
▸ 축약어는 되도록 자제하자. 축약어 사용은 팀내에서 허락된것만.
▸ 가능한 상세하게 적자.
30. 이름 규칙(NAMING)
타입 이름, 변수이름
▸ 클래스 , 구조체 등 타입 이름은 단어 단위로 앞글자가 대문자로
선언 해준다. 클래스 이름이 잘 무엇을 수행하는지 알 수 있게
이름을 짓자.
▸ 변수는 모두 소문자로 작성, _ 언더 스코어를 이용하여 변수라는
의미를 나타내준다. (google은 뒤에 붙인다.)
클래스 변수
31. 이름 규칙(NAMING)
함수 이름 ,네임스페이스 이름
▸ 함수는 대소문자가 섞인 방식을 사용함.
언더스코어는 사용지 않음.
▸ 네임스페이스는 모두 소문자로 작성.
함수 네임스페이스
32. COMMENT(COMMENT)
주석
▸ 의미있는 주석을 사용하고, 정확한 의미를 전달.
▸ 너무 많은 주석 남발은 보기 힘드니 한줄 한줄마다 작성보다는.
한 기능 수행 단위로 쓰는게 적합.
▸ 아직 완벽하지 않거나 진행중인 Code는 TODO 주석을 달아주고
완성시 반드시 지워주자.