본문 바로가기

전체 글57

항목 39. private 상속은 심사숙고해서 구사하자 public 상속(is- a 관계)이 아닌 private 상속을 살펴보자. class Person {…}; class Student : private Person { … }; //private 상속 void eat(const Person& p); // 사람이든 학생이든 먹을 수 있다. void study(const Student& s); // 공부는 학생만할 수 있다. Person p; Student s; eat(p); // OK ! p는 Person의 일종이다. eat(s); // Error! Student는 Person의 일종이 아니다.(public 상속이 아니기 때문에) 1. private 상속의 특징 1) 파생클래스 객체(Student)에서 기본클래스 객체(Person)로 변환하지 않는다. * 기.. 2020. 3. 16.
항목 38. "has-a(…는 …를 가짐)" 혹은 "is-implemented-in-terms-of(…는…를 써서 구현됨)"를 모형화할 때는 객체 합성을 사용하자 1. 결론 : public 상속을 할 수 없다면, 객체합성(has-a, is-imple…)을 사용하자 2. 용어정리 1) 합성(composition) - 어떤 타입의 객체들(ex. Person)이 다른타입의 객체들(ex. Address, Phonenumber)을 포함할때, 성립하는 관계를 뜻함 class Address {…}; class Phonenumber {…}; class Person{ private: string name; Address address; Phonenumber pn; }; 2) 객체합성 - has-a, is-imple… 두가지 뜻으로 나뉜다. why? - sw개발자는 2가지 영역을 마주하기 때문이다. 3) 2가지 영역과 객체합성 (1) 응용영역 - 실제로 가치가 있는 데이터를 다룸(.. 2020. 3. 12.
항목 37. 어떤 함수에 대해서도 상속받은 기본 매개변수 값은 절대로 정의하지 말자 지금까지 다른 c++책을 보면 다형성에 대해 배웠던 적이 있을텐데(가상함수 바인딩), 여기서 설명할 것은 "기본 매개변수 값이 설정된" 가상함수를 바인딩하게 되면 뭔가 꼬이기 시작한다. class Shape{ public : enum ShapeColor { Red, Green, Blud }; virtual void draw(ShapeColor color = Red) const = 0; }; class Rectangle : public Shape { public : virtual void draw(ShapeColor color = green) const; }; class Circle : public Shape{ public : virtual void draw(ShapeColor color) const; }.. 2020. 3. 10.
항목 36. 상속받은 비가상 함수를 파생 클래스에서 재정의하는 것은 절대 금물! 1. 바인딩 : 프로그램 소스에 쓰인 각종 내부 요소, 이름, 식별자들에 대해 값 혹은 속성을 확정하는 과정을 일컫는다. 빌드중에 이과정이 일어나면 정적바인딩, 실행중에 일어나면 동적바인딩 c++에서 가상함수 바인딩은 문서상으로 동적바인딩이나, 실제로는 런타임 성능을 높익기 위해 정적 바인딩을 쓴다. 컴파일 중에 가상함수테이블을 파생 클래스에 맞게 바꿈으로서 정적바인딩처럼! ex) "int foo = 2;" 일때 데이터타입이 int인것과 변수명이 foo로 정해지는게 정적바인딩이고 foo 변수에 2가대입되는게 동적바인딩이다! lass B{ public : void mf(); // 비가상함수 }; class D : public B{ public : void mf(); //비가상함수 재정의 }; B *pB =.. 2020. 3. 10.
항목 35. 가상 함수 대신 쓸 것들도 생각해 두는 자세를 시시때때로 길러 두자 34장에서 봤던 것 처럼, 가상함수는 클래스 설계자가 기본 정의를 제공하기 때문에, 재정의를 하지 않아도 작동한다. 하지만, 정작 다른작동을 해야할때 까먹고 재정의를 하지 않으면.. 디버깅이 아주 힘들어질 것이다. 이번장은 이러한 문제를 해결하기 위해, 가상함수를 대체할 무엇인가가 필요하다는 주제로 쓰였다. 1. NVI 관용구(Non Virtual Interface) class GameCharacter{ public : int healthValue() const { // 파생클래스는 해당함수 재정의 불가 … // 사전동작 int retVal = doHealthValue(); .. // 사후동작 } private : virtual int doHealthValue() const { //파생클래스는 해당가상함.. 2020. 3. 10.
항목 34. 인터페이스 상속과 구현 상속의 차이를 제대로 파악하고 구별하자 클래스 설계입장에서 다음과 같이 상속받고 싶게한다. 1. 멤버함수의 인터페이스(선언)만을 상속 2. 선언, 구현, 그리고 오버라이딩(재정의)까지 가능하게 3. 선언, 구현만 상속 가능하게 class shape{ public: virtual void draw() const = 0; // 1. 순수 가상함수 virtual void error(const std::string& msg); // 2. 비순수 가상함수 int objectID() const; // 3. 비가상함수 … }; class Rectangle: public Shape { … } ; class Ellipse: public Shape { … } ; 1. 순수 가상함수 순수 가상함수는 파생클래스에게 선언만을 물려준다. (파생클래스가 순수가상함수를 .. 2020. 3. 9.