본문 바로가기

PROGRAMMING/Effective Modern C++24

16. const 멤버 함수를 스레드에 안전하게 작성하라. - 동시적 문맥에서 쓰이지 않을 것이 확실한 경우가 아니라면, const 멤버 함수는 스레드에 안전하게 작성하라. 다항식을 대표하는 클래스를 만든다고 하자. 이 클래스가 유용하려면 다항식의 근을 계산하는 멤버 함수를 갖추어야 할 것이다. 그런 함수는 다항식을 수정하지 않을 것이므로, const로 선언하는 것이 자연스럽다. 다항식 근의 계산 비용이 클 수 있으므로, 꼭 필요할 때에만 계산하는 것이 바람직하다. 즉, 필요할 때에만 근(들)을 실제로 계산해서 캐시에 저장하고, 그렇지 않을 때에는 그냥 캐시에 있는 값을 돌려주도록 구현하는 것이 바람직하다. class Polynomial { public: using RootsType = std::vector; RootsType roots(void) const {.. 2021. 3. 9.
15. 가능하면 항상 constexpr을 사용하라. - constexpr 객체는 const이며, 컴파일 도중에 알려지는 값들로 초기화된다. 컴파일 시점에 알려지는 값들에는 특별한 권한이 있다. 예를 들어 그런 값들을 읽기 전용 메모리에 배치될 수 있다. 좀 더 광범위한 프로그래머들에게 중요한 점은, 상수이자 컴파일 시점에 알려진 정수 값을 C++에서 정수 상수 표현식이 요구되는 문맥에서 사용할 수 있다는 것이다. 배열 크기나 정수 템플릿 인수, 열거자 값, 정합 지정자를 지정하는 등의 여러 문맥이 그런 문맥에 해당한다. int sz; // 비constexpr 변수 constexpr auto arraySize1 = sz; // 오류! sz의 값이 컴파일 도중에 알려지지 않음 std::array data1; // 오류! 같은 문제 constexpr auto .. 2020. 12. 27.
14. 예외를 방출하지 않을 함수는 noexcept로 선언하라. - noexpcet는 함수의 인터페이스의 일부이다. 이는 호출자가 noexcept 여부에 의존할 수 있음을 뜻한다. C++98에서 예외 지정은 다소 변덕 스러운 야수였다. 함수 구현이 바뀌면 예외 지정도 바뀔 가능성이 생겼고, 기존의 예외 지정에 의존하던 클라이언트 코드는 깨질 수 있었다. 게다가, 대체로 컴파일러는 함수구현과 게다가, 대체로 컴파일러는 함수 구현과 예외 지정, 그리고 클라이언트 코드 사이의 일관성 유지에 아무런 도움도 주지 않았다. 그래서 대부분의 프로그래머는 결국 C++98의 예외 지정이 득보다 실이 크다고 판단하게 되었다. C++11 제정 과정에서, 함수의 예외 방출 행동에 관해 정말로 의미 있는 정보는 함수가 예외를 하나라도 던질 수 있는지 아니면 절대로 던지지 않는지의 여부라는 .. 2020. 12. 27.
13. iterator보다 const_iterator를 선호하라. - itorator보다 const_iterator를 선호하라. 가능한 한 항상 const를 사용하는 것이 좋다. 하지만 프로그래머들은 가능한 한 항상 const를 사용하지 않는다. 실용적일 때에만 항상 사용할 뿐이다. 그리고 C++98에서 const_iterator는 그리 시용적이지 못하다. 왜냐하면 C++98에서는 비상수 컨테이너로부터 const_iterator를 얻는 방법도 까다로웠고, 삽입/삭제 위치를 iterator로만 지정할 수 있었기 때문이다. 하지만 C++11에서는 C++98에서의 문제점들이 개선되었다. 따라서 C++11 환경에서 프로그래밍을 한다면 가능한 한 iterator 보다 const_iterator를 사용하는 것이 좋다. 예를 들어 std::vector에서 1983이라는 값이 처음 .. 2020. 12. 26.