본문 바로가기

study/C++

[C++][Effective C++] 00. Effective C++ 들어가면서

728x90

[Effective C++(3판)]에 대한 내용을 공부하면서 정리한 내용이다.


요약

이 책은 C++를 보다 효과적으로 쓰기 위해 작성되었다. C++ 개발을 하면서 자주 마주치는 C++ 프로그래밍의 이모저모를 다루는 내용이다. 합쳐서 보다 효과적으로 사용하도록 해보자. 다만, 별도 행령 강령 따위가 아니고 바이블이 아니다. 그저 지침(Guideline)일 뿐이다. 책을 통해서 C++가 어떻게 동작하는지 또는 왜 이렇게 동작하는지 이해하고, 독자가 어떤 용도에 어떻게 쓸 수 있을 지에 대해서 안목을 길러야 한다.

 

이 책에서는 크게 아래 2가지에 대해 다루고 있다.

  1. 일반적인 설계 전략
  2. C++ 만의 언어적 특징에 관련된 실전 세부사항
    • 상속 vs 템플릿
    • public 상속 vs private 상속
    • private 상속 vs 클래스 합성
    • ...

 

책은 표준(Standard) C++을 기준으로 설명하고 있다. 따라서, 어느 한 플랫폼에 친화적이지 않다. 그런 것을 원하는 경우 별도로 찾아봐야 한다.

또, 스레딩에 대해서도 다루지 않는다. C++11 부터는 std::thread 가 지원되기는 하지만, 본 책이 나왔던 시점에서는 C++ 언어 차원에서 스레드에 대한 개념이 없었기 때문이다. pthread는 외부 라이브러리이며, 표준 라이브러리가 아니다. 따라서, 이 부분도 별도로 확인해야 한다. 다만, 다중 스레드 환경은 요즘 기본적으로 사용되며, 중요한 개념이기 때문에 책에서는 다중 스레드 환경에서 문제 될 부분을 지적하는 정도로 타협한다.

 

시그니처

기본적으로 함수의 선언문에서 시그니처는 매개변수 리스트를 의미한다. 하지만, 책에서는 반환값까지 추가해서 사용하고 있다. 쓸모가 많기 때문이다.

예를 들어, std::size_t numDigits(int num);으로 함수 numDigits를 선언했다면, numDigits의 시그니처는 std::size_t (int num)으로 한다.

 

explicit 생성자

explicit 생성자는 예상치 못한 타입 변환을 막아 효과적이다. 암시적 타입 변환을 하지 않는 이상 생략해도 무방하다.

 

복사 생성자 vs 복사 대입 생성자

복사 생성자와 복사 대입 생성자는 처음 보면 헷갈릴 수 있지만, 쉽게 구분이 가능하다.

A(const A &other); 				// 복사 생성자
A &operator=(const A &other); 	// 복사 대입 연산자

A a1; 			// 일반 생성자 호출
A a2(a1); 		// 복사 생성자 호출
A a3 = a1; 		// 복사 생성자 호출
a2 = a1; 		// 복사 대입 연산자 호출

 

새로운 객체가 새로 정의되는 것이라면, 복사 "생성자"가 호출되는 것만 기억하면 된다. 아래 코드와 같이 함수 내 인자를 전달할 때 pass-by-value를 하게 되어도, 복사 생성자가 호출된다.

void func(A a);
..
A a1;
if ( func(a1) ) // func() 호출 시, a로 a1에 대해 복사 생성자가 호출 됨
...

 

미정의 동작(undefined behavior)

C++ 개발 시, 미정의 동작을 주의해야 한다. 미정의 동작에 의해 Exception이 발생하고 Core가 떨어질 수 있다. 대표적으로 미정의 동작이 발생하는 경우는 아래와 같다.

  • NULL 포인터의 역참조 수행
  • 유효하지 않은 배열의 인덱스 참조
  • ...

뒤의 내용들을 설명하기 위해 책에 대한 개괄적인 내용을 다뤘고, C++ 개발에 대한 개괄적인 내용을 다뤘다.

앞으로 55가지 테크닉에 대해 정리하면서, 여러 다른 테크닉을 호출할 때도 있고 그때그때 설명을 해주는 경우도 있다. 맨 앞 내용이라 그런지 가볍게 읽는 내용이었다.

728x90