파생 클래스가 기본 클래스를 상속할 때 키워드로 public, private, protected를 사용한다.
pubic 상속은 is-a(...는 ...의 일종이다)를 의미한다는 것을 기억하자. private 상속은 의미 자체가 완전히 다르다(39장 참고). protected는 요즘 의미가 애매하다고 하다.
간단한 애기인데 매개변수에 기본 클래스의 객체나 포인터 참조자를 요구하는 함수는 파생 클래스의 객체 포인터, 참조자도 받아 들일 수 있다.
즉, 파생 클래스는 기본 클래스의 매개변수에 들어갈 수 있다. 반대로 기본 클래스는 파생 클래스의 매개변수에 들어갈 수 없다.
class Person { };
class Student : public Person { };
void Eat(const Person& p); //매개변수로 기본 클래스 요구
void Study(const Student& s); //매개변수로 파생 클래스 요구
int main()
{
Person p; //기본 클래스
Student s; //파생 클래스
Eat(p); //문제x
Eat(s); //문제x
Study(p); //에러
Study(s); //문제x
system("Pause");
return 0;
}
public 상속이 is-a 관계라는 의미만 두고 잘못 판단하는 경우가 있다.
만약 펭귄, 참새같은 새(bird)를 구현한다고 하면 새(bird)를 기본 클래스로 두고 펭귄, 참새를 파생 클래스로 만들 것이다.
class Bird
{
public:
virtual void Fly();
};
class Penguin : public Bird { };
class Sparrow : public Bird { };
위의 코드를 보면 펭귄은 날 수 있다. 하지만 펭귄은 날지 못한다.
컴파일은 이 오류를 찾지 못한다.
두 가지 방법으로 처리를 할 수 있을 것이다.
1.클래스 상속 구조를 세분화 한다.
class Bird { };
class FlyingBird : public Bird
{
public:
virtual void Fly();
};
class Penguin : public Bird { };
class Sparrow : public FlyingBird { };
Bird를 상속하는 FlyingBird를 하나 더 만든다. 날 수 있는 새는 FlyingBird를 상속하면 된다.
2.에러 처리를 한다.
class Bird
{
public:
virtual void Fly();
};
class Penguin : public Bird
{
public:
virtual void Fly() override
{
assert(false); //터트림
}
};
이 방법은 생각해 봐야할 것이 펭귄은 날 수 없다가 아니라 펭귄은 날 수 있으나 날려고하면 프로그램이 터진다이다.
코드를 직접 보는게 아닌 이상 클래스 사용자는 프로그램이 터지는 경험을 할 법하다.
public 상속은 기본 클래스 객체가 가진 모든 것들이 파생 클래스 객체에도 그대로 적용된다고 단정하는 상속이다.
컴파일러 수준에서는 문법적 하자가 없기 때문에 무사히 통과되지만, 무사통과된 코드가 제대로 동작하리란 보장은 없다. 클래스 사이에 맺을 수 있는 관계로 is-a 외에 has-a(...는 ...를 가짐), is-implemented-in-terms-of(...는 ...를 써서 구현)이 있다(38장, 39장 참고).
이것만은 잊지 말자
public 상속의 의미는 is-a(...는 ...의 일종)이다.
기본 클래스에 적용되는 모든 것들이 파생 클래스에 그대로 적용되어야 한다.
모든 파생 클래스 객체는 기본 클래스 객체의 일종이기 때문이다.
'서적 정리 > Effective C++' 카테고리의 다른 글
36.상속받은 비가상 함수를 파생 클래스에서 재정의하는 것은 절대 금물! (0) | 2021.12.22 |
---|---|
35.가상 함수 대신 쓸 것들도 생각해 두는 자세를 시시때때로 길러 두자 (0) | 2021.12.21 |
34.인터페이스 상속과 구현 상속의 차이를 제대로 파악하고 구별하자 (0) | 2021.12.21 |
33.상속된 이름을 숨기는 일은 피하자 (0) | 2021.12.20 |
31.파일 사이의 컴파일 의존성을 최대로 줄이자 (0) | 2021.12.20 |
30.인라인 함수는 미주알고주알 따져서 이해해 두자 (0) | 2021.12.19 |
29.예외 안전성이 확보되는 그날 위해 싸우고 또 싸우자! (0) | 2021.12.19 |
28.내부에서 사용하는 객체에 대한 "핸들"을 반환하는 코드는 되도록 피하자 (0) | 2021.12.19 |
댓글