서적

    항목 8: 0과 NULL보다 nullptr를 선호하라

    리터럴 0은 int이지 포인터가 아니다. NULL도 포인터 형식이 아니라는 점. void f(int);//f의 3 가지 오버로딩 void f(bool); void f(void*); f(0);//f(int) 호출 f(NULL)//보통 f(int) 호출 nullptr의 장점은 정수 형식이 아니다. 사실 포인터 형식도 아니다? 이 책보면서, 아쉬운건 번역이나 뭔가 어순?이 안 맞음. 내 맞춤법 마냥 답 없음 nullptr의 실제 형식은 std::nullptr_t인데, std::nullptr_t 자체는 다시 "nullptr의 형식"으로 정의(순환 정의) f(nullptr);//f(void*) 오버로딩 호출 nullptr 은 코드의 명확성 높여준다. auto result = findRecord(...); if(r..

    항목 51: new 및 delete를 작성할 때 따라야 할 기존의 관례를 잘 알아 두자

    기존의 관례에 잘 맞는 operator new를 구현하려면 다음의 요구사항만큼은 기본으로 지켜야 합니다. - 반환 값이 제대로 되어 있어야 합니다. - 가용 메모리가 부족할 경우에는 new 처리자 함수를 호출(항목 49) - 크기가 없는 (0byte) 메모리 요청에 대한 대비책 - 기본 형태의 new가 가려지지 않도록 해야합니다. void* operator new(std::size_t size) throw(std::bad_alloc) { using namespace std; if(size == 0) { size = 1; } while (true) { //size 바이트를 할당 if(/*할당 성공*/) { return (/*할당된 메모리에 대한 포인터*/); } //할당 실패 시, 현재 new 처리자 함수..

    항목 49: new 처리자의 동작 원리를 제대로 이해하자

    operatore new 함수는 예외를 던지게 되어 잇습니다. 메모리 할당이 제대로 되지 못한 상황에 대한 반응으로 operator new가 예외를 던지기 전에, 이 함수는 사용자 쪽에서 지정할 수 있는 에러 처리 함수를 우선적으로 호출하도록 되어 있는데, 이 에러 처리 함수를 가리켜 new 처리자라고 합니다. set_new_handler는 new_handler를 받고 new_handler를 반환하는 함수입니다. 즉, set_new_handler가 받아들이는 new_handler 타입의 매개변수는 요구된 메모리를 operator new가 할당하지 못했을 때 operator new가 호출할 함수의 포인터입니다. new 처리자 함수가 다음 동작 중 하나를 꼭 해주어야함. - 사용할 수 있는 메모리를 더 많이..

    항목 7: 객체 생성 시 괄호(())와 중괄호({})를 구분하라

    C++11에서는 객체 생성 구문이 아주 다양해졌다. C++ 에서는 Class 개념이 있기 때문에 초기화와 배정이 각자 다른 함수들을 호출한다. 정확하게 괄호/중괄호를 이해하고 써야하는 이유이다. 중괄화 초기화를 선호한다. 절대 여기만 보고 페이지 넘기지마세요~ 초반에만 중괄호 초기화에 대한 내용을 기술하고, 후반부터는 단점을 기술한다. 장점 1: narrowing conversion을 방지 double x, y, z; int sum1{ x + y + z};//오류! double들의 합을 int로 표현하지 못할 수 있음 괄호나 "="를 이용한 초기화는 이러한 좁히기 변환을 점검하지 않는다. 장점 2: 가장 성가신 구문 해석에 자유롭다는 점 가장 성가신 구문 해석은 "선언으로 해석할 수 있는 것은 항상 선언..

    항목 6: auto가 원치 않은 형식으로 연역될 때에는 명시적 형식의 초기치를 사용하라

    항목 5에서 설명했듯이, auto를 사용해서 변수를 선언하면 형식을 명시적으로 지정했을 때보다 기술적으로 여러 가지 장점이 있다. 그러나 가끔은 auto의 형식 연역이 딴전을 부리기도 한다. Widget w; ... bool highPriority = features(w)[5];//w의 우선순위가 높은가? ... processWidget(w, highPriority);//w를 그 우선순위에 맞게 처리한다 해당 코드는 잘 작동하지만, 아래 코드는 예측할 수 없다. auto highPriority = features(w)[5];// w의 우선순위가 높은가? processWidget(w, highPriority);//미정의 행동 auto를 사용하는 버전에서 highPriority의 형식은 더 이상 bool이 ..

    항목 5: 명시적 형식 선언보다는 auto를 선호하라

    먼저, Effective Modern C++을 책을 읽기 시작했습니다. 항목 1~4는 어딨을까요? 필자는 템플릿을 문법만 알지.. 잘 쓰지 못한다.. 그래서 잠깐 스킵 auto 의 장점 1. 변수의 초기화를 빼먹는 실수를 방지한다. int x1;//문맥에 따라서는 초기화되지 않을 수 있음 auto x2;//Error auto x3 = 0; //Ok 2. 반드시 형식을 지정해줘야 하는 경우보다 편리성과 효율성에서 장점을 가진다. std::function 객체를 통해서 클로저를 호출하는 것은 거의 항상 auto로 선언된 객체를 통해 호출하는 것보다 느리다. 메모리와 시간을 더 많이 소비한다. 와우....처음 알았음.. 3.32 bit -> 64bit 이식할 때 문제 방지를 할 수 있다. 4. 리팩토링의 장점..

    항목 36: 상속 받은 비가상 함수를 파생 클래스에서 재정의하는 것은 금물!

    - 비가상함수는 정적 바인딩 - 가상함수는 동적 바인딩 - 상속받은 비가상 함수를 재정의하는 일은 절대로 하지 맙시다.

    항목 35: 가상함수 대신 쓸 것들도 생각해 두는 자세를 시시때때로 길러 두자

    - 비가상 인터페이스 관용구를 통한 템플릿 메서드 패턴 - 가상 함수는 반드시 private 멤버로 두어야한다. - 사용자로 하여금 public 비가상 멤버 함수를 통해 private 가상 함수를 간접적으로 호출하게 만드는 방법 - 함수 포인터로 구현한 전략 패턴 - std::function - 고전적인 전략 패턴 - 한 쪽 클래스 계통에 속해 있는 가상 함수를 다른 쪽 계통에 있는 가상 함수로 대체

    항목 34: 인터페이스 상속과 구현 상속의 차이를 제대로 파악하고 구별하자

    - 순수가상함수를 선언하는 목적은 파생 클래스에게 함수의 "인터페이스"만을 물려주려는 것 - 단순 가상함수를 선언하는 목적은 파생 클래스로 하여금 함수 인터페이스뿐만 아니라 그 함수의 기본 구현도 물려받게 하자는 것 - 비가상함수를 선언하는 목적은 파생클래스가 함수 인터페이스와 더불어 그 함수의 필수적인 구현을 물려 받게 하는 것 - 결정적인 실수 두 가지를 피하자 - 모든 멤버 함수를 비가상함수로 선언하는 것을 피하자 - 모든 멤버함수를 가상함수로 선언하는 것을 피하자 - 인터페이스 상속은 구현 상속과 다릅니다. public 상속에서, 파생 클래스는 항상 기본 클래스의 인터페이스를 모두 물려 받습니다.

    항목 33: 상속된 이름을 숨기는 일은 피하자

    - 어떤 기본 클래스로부터 상속을 받으려고 하는데, 오버로드된 함수가 그 클래스에 들어있고 이 함수들 중 몇 개만 재정의하고 싶다면, 각 이름에 대해 using 선언을 붙여주어야한다. - 파생클래스의 이름은 기본클래스의 이름을 가립니다. - 파생 클래스의 이름은 기본 클래스의 이름을 가립니다. public 상속에서는 이런 이름 가림 현상은 바람직하지 않습니다. - 가려진 이름을 다시 볼 수 있게 하는 방법으로, using 선언 혹은 전달 함수를 쓸 수 있습니다.