본문 바로가기

Programming/Effective C++ 3판12

항목 6. 컴파일러가 만들어낸 함수가 필요 없으면 확실히 이들의 사용을 금해 버리자. 하나밖에 없는 클래스 즉, 똑같은게 없는 클래스를 만든다고 할 때 객체는 사본(copy)를 만드는 것 자체가 이치에 맞지 않다. 그러다 보니 객체를 복사하려 하는 코드는 컴파일이 되지 않게 하려면 어떻게 해야 할까? HomeForSale h1; HomeForSale h2; HomeForSale h3(h1); // h1을 복사하려 한다. - 컴파일이 되면 안된다. h1 = h2; // h2를 복사 하려 한다. - 컴파일이 되면 안된다. 해결 방법 - 컴파일러가 생성하는 복사 생성자와 복사 대입 연산자는 public 으로 자동 생성 해버리므로 이들을 private 멤버로 선언 하면 된다. ㄴ 효과1 : 클래스 멤버 함수가 명시적으로 선언되어 컴파일러는 자시느이 기본 버전을 만들 수 없다. ㄴ 효과2 : 비공.. 2008. 6. 27.
항목 5. C++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을 세우자 복사 생성자, 복사 대입 연산자, 생성자, 소멸자 는 사용자가 선언을 하지 않아도 컴파일러가 자동으로 public inline 함수로 선언해 버린다. calss Empty{}; class Empty { public: Empty() { ... } // 기본 생성자 Empty(const Empty& rhs) { ... } // 복사 생성자 ~Empty() { ... } // 소멸자 Empty& operator= (const Empty& rhs) { ... } // 복사 대입 연산자 위의 두 클래스는 같다고 보면 된다. 참조 1. 복사 생성자를 제외한 생성자를 선언하면 컴파일러가 기본 생성자는 만들지 않는다. 이것만은 잊지 말자! - 컴파일러는 경우에 따라 클래스에 대해 기본 생성자, 복사 생성자, 복사 대입.. 2008. 6. 27.
항목 4. 객체를 사용하기 전에 반드시 그 객체를 초기화하자. 초기화되지 않은 값을 읽도록 내버려 두면 정의되지 않은 동작이 그대로 흘러 나오게 된다. 모든 객체를 사용하기 전에 항상 초기화 하자! 기본제공 타입으로 만들어진 비멤버 객체에 대해서는 초기화를 손수 해야 한다. int x = 0; // int의 직접 초기화 const char* text = "A C-style string"; // 포인터의 직접 초기화 double d; // 입력 스트림에서 읽음으로써 std::cin >> d; // "초기화" 수행 이런 부분을 제외하고 나면, C++의 초기화의 나머지 부분은 생성자로 귀결된다. 생성자에서 지킬 규칙은 간단하다. 그 객체의 모든 것을 초기화하자! 단 대입(assignment)을 초기화(initialization)와 헷갈리지 말자! class PhoneNu.. 2008. 6. 10.
항목 3. 낌새만 보이면 const를 들이대 보자! const 사용처 클래스 바깥에서는 전역 혹은 네임스페이스 유효범위의 상수를 선언(정의)하는 데 쓸 수 있다. 파일, 함수, 블록 유효범위에서 static으로 선언한 객체에도 const를 붙일 수 있다. 클래스 내부의 경우 정적 멤버 및 비정적 데이터 멤버 모두를 상수로 선언할 수 있다. char greeting[] = "Hello"; char *p = greeting; // 비상수 포인터, 비상수 데이터 const char *p = greeting; // 비상수 포인터, 상수 데이터 char * const p = greeting; // 상수 포인터, 비상수 데이터 const char * const p = greeting; // 상수 포인터, 상수 데이터 void f1(const Widget *pw); .. 2008. 6. 10.
항목 2. #define을 쓰려거든 const, enum, inline을 떠올리자. 이유 1. 컴파일러는 선행 처리자를 밀어버리고 숫자 상수로 바꾸어 버리기 때문이다. #define ASPECT_RATIO 1.653 위와 같이 코드를 썻다고 하면 ASPECT_RATIO 라는이름은 컴파일러가 쓰는 기호 테이블레 들어가지 않는다. 그래서 숫자 상수로 대체된 코드에서 컴파일 에러라도 발생하게 되면 골치가 아플 수 있다. 소스 코드엔 분명히 ASPECT_RATIO가 있었는데 에러 메시지엔 1.653이 있으니 말이다. 해결책 1. 매크로 대신 상수를 사용하자. const double AspectRatio = 1.653; AspectRatio는 언어 차원에서 지원하는 상수 타입의 데이터이기 때문에 당연히 컴파일러의 눈에도 보이며 기호 테이블에도 당연히 들어간다. 게다가 상수가 부동소수점 실수 타입.. 2008. 5. 29.
항목 1. C++를 언어들의 연합체로 바라보는 안목은 필수 초창기의 C++는 단순한 C 언어에 객체 지향 기능 몇 가지가 결합된 형태였으나 꾸준한 성장을 거쳐 아이디어, 기능, 프로그래밍 전략들을 취해 자기 것으로 만드는 데 있어 점점 대담하고 과감한 행보를 보였다. 이렇게 발전한 C++는 다중패러다임 프로그래밍 언어라고 불리운다. 절차적 프로그래밍을 기본으로 객체 지향, 함수식, 일반화 프로그래밍을 포함하여 메타프로그래밍 개념까지 지원하고 있다. C++를 적절히 사용하기 위해서 C++를 단일 언어로 바라보는 눈을 넓혀, 상관 관계가 있는 여러 언어들의 연합체로 보자. 이렇게 해 가면 시각이 단순해지고 명확해지며, 기억하기도 편해 진다. C++는 4개의 하위 언어를 제공한다. 제공하는 하위 언어는 다음과 같다. C : C++는 여전히 C를 기본으로 하고 있다. .. 2008. 5. 28.