본문 바로가기

전체 글57

항목 33. 상속된 이름을 숨기는 일을 피하자 유효범위(scope)에 대해 알고있을 것이다. int x; // 전역변수 void func() { double x; //지역변수 cin >> x; // 지역변수 double x를 입력받는다. } 컴파일러가 x를 추적할때 func함수를 먼저 살핀다. 타입은 중요치않다. 어쨌든 double x가 int x의 이름을 가리게 된다. 이제 상속얘기를 해보자. 기본 클래스에 속해 있는것을 파생클래스가 참조한다면 컴파일러는 이 참조대상을 바로 찾을 수 있다. class Base{ private: int x; public: virtual void mf1() = 0; //순수 가상함수 virtual void mf2(); // 가상함수 void mf3(); // 비가상함수 }; class Derived : public B.. 2020. 3. 9.
항목 32. public 상속 모형은 반드시 "is-a"를 따르도록 만들자 c++ 객체지향에서 public 상속은 "is-a(…는 …의 일종이다)"를 의미 Derived가 Base로부터 public 상속을 받았다면, D is a B (D는 B의 일종이다. 하지만, B는 D의 일종이 아니다.) ex) 학생은 사람의 일종이다, 사람은 학생의 일종이 아니다 새는 날 수 있다. 펭귄은 새이다. 펭귄은 날수 있다? 기본 클래스의 가정이 잘 못되어있다. 여기서 확인할 수 있는것은 public 상속시, 기본 클래스 객체가 가진 모든 것들이 파생 클래스 객체에도 그대로 적용된다고 단정하는 상속이다. 참고 클래스간 맺을 수 있는 관계는 "is -a" 말고도 "has-a", "is-implemented-in-terms-of"방식이 있다. 38,39장에서 알아보자. 이것만은 잊지 말자 - publ.. 2020. 3. 9.
항목 30. 인라인 함수는 미주알고주알 따져서 이해해 두자 1. 인라인함수 : 말그대로 본문의 코드를 바꿔치기 하는 함수. 호출비용 X, 코드 비대화 가능성 있음 (짧게 사용시, 대체되는 코드 크기보다 호출 비용이 작으면 효율적임) 2. 아웃라인함수 : 일반함수 호출 인라인함수는 명시적, 암시적으로 사용할 수 있다. class Person{ public: int age() const { return theAge;} // 암시적 private: int theAge; }; // 참고 : 프렌드 함수도 클래스 내부에서 정의가능함.. (명시적 : inline이라고 명시한다.) 3. 인라인함수를 명시적으로 사용하더라도 컴파일러가 보기에 복잡하면, 인라인 대상으로 삼지 않는다. 예를 들면, (1) 재귀 (2) 루프 (3) virtual이 있는경우, (4) 함수의 주소를 취.. 2020. 3. 6.
항목 29. 예외 안전성이 확보되는 그날 위해 싸우고 또 싸우자 예외에 대한 안전성을 갖춘 코드는 다음 항목을 지켜야한다. 1. 자원이 새도록 하지 않는다. 2. 자료구조가 더럽혀지는 것을 허용하지 않는다. 아래 예를 살펴보자. class PrettyMenu { public: void changeBackground(istream& imgSrc); private: Mutex mutex; Image *bgImage; int imageChanges; }; void PrettyMenu::changeBackground(istream& imgSrc) { lock(&mutex); delete bgImage; imageChanges++; // error 1 bgImage = new Image(imgSrc); // error 2 unlock(&mutex); } * 해설 - error.. 2020. 3. 5.
항목 28. 내부에서 사용하는 객체에 대한 '핸들'을 반환하는 코드는 되도록 피하자 사각형 클래스로부터 시작해보자. 메모리 효율을 높이기 위해 꼭짓점(Point)을 별도의 구조체(RectData)에 넣어 사각형클래스(Rectangle)가 이를 가리키도록 해보자. class Point{ public: Point(int x, int y); void setX(int newVal); void setY(int newVal); }; struct RectData{ Point ulhc ; // 좌측상단 Point lrhc ; // 우측하단 }; class Rectangle { private: std::tr1::shared_ptr pData; public: // 아래 두행은 전부 상수멤버함수임을 기억하자. Point & upperLeft() const { return pData->ulhc; } // 좌.. 2020. 2. 4.
항목 27. 캐스팅은 절약, 또 절약! 잊지 말자 1. 캐스트 방법 (1) C스타일의 캐스트 -> 구형스타일 1) (T) 표현식 2) T(표현식) : 함수방식의 캐스트 (2) C++스타일의 캐스팅 1) const_cast - 객체의 상수성을 없앰 2) dynamic_cast - 다운캐스팅, 런타임 비용이 크다. 3) reinterpret_cast 4) static_cast - 일반적인 캐스트, 포인터타입은 상속관계에 있는경우만 변환가능하다. * 참고 - 대부분 개발자들은, 캐스팅이 컴파일러에게 알려주는용도만으로 알고 있지만, 실상은 그렇지않다. 타입변환시 런타임에 실행되는 코드가 꽤 있다. 즉 런타임 비용이 든다는것이다. 2. 캐스팅 이슈 (1) 런타임 비용 발생 예제 class Base{...}; class Derived:Base{...}; Deriv.. 2020. 2. 3.