내가 C++에 조예가 깊어서 글을 남기는 것이 아니라, Effecitve C++ 을 공부하는 사람들이 이 글을 보고, 도움이 되었으면 하는 생각과, 혹시 내가 틀린것이 있다면 지적해 주시지 않을까 란 생각으로 글을 올리는것임을 미리 밝힙니다.
본론으로 들어와서, 나는 설계 단계에서 다중 상속 할까낭~ 하는 생각을 한적은 있었지만, 지금까지 다중 상속을 해서 코딩한적은 없다. 왜냐하면, 일단 설계단계 조차 난해하고, 조금 복잡해지는 경향이 있었다. 그래서 스스로가 "지금 여기에 꼭 필요한가?" 란 질문에 항상 "지금은 아니오" 라고 답하곤 했기 때문이다.
이번 항목 40의 제목처럼 "다중 상속은 심사숙고해서 사용하자" 로 이야기 하고 있다. 그렇다면 나는 이런 생각을 하곤 한다. "왜!? 무엇 때문에!?"
다중 상속을 왜 심사숙고 해야 하는가?
1. 함수의 모호성 : 코드로 보는게 이해가 더 빠르다.
함수 및 변수의 모호성을 보여주는 코드이다. 이 코드로 확인 할수 있듯이 어떤 Draw 를 호출했는지 .. 그 누구도 모르게 된다. 설령 인터페이스가 public 과 private 에 각각 Draw 가 있다 하더라도, C++ 컴파일러가 함수의 적법성 검사 할때, 모호성 에러를 발견하게 되어, 역시 컴파일 에러를 뱉어준다.
사실 이런것들은 사용자가 손쉽게 피해갈 수 있을것이다. 하지만 다음에 나오는 상황에서도 그럴까?
2. 멤버 변수의 모호성 : 코드로 보는게 이해가 더 빠르다.
이처럼 Base_var 에서 모호성이 발생한다. 이런 다이아몬드 상속 형태에선 ... 어떻게 손 쓸 방법이 없어진다. 이런 모호성을 없애기 위해, 참 편한 키워드 virtual 이 있다. 즉 가상 상속인데, 사용 법은 아래 코드를 첨부 했다.
이처럼 하면 된다.
언뜻 생각해 보면, 상속 받을 때 virtual 상속을 하면, 다 해결 될 듯한 생각도 든다. 이런 모호성도 없애줄 뿐만 아니라, 다중 상속을 보다 쉬울 수도 있을 것이다 ㅋ.
하지만 사람이 봐도 복잡한 이런 상속은 컴파일러 입장에서 봐도 처리하기 복잡하다. 이러한 처리 때문에, 가상 상속을 하는 클래스로 만든 객체의 크기는 일반 객체의 크기보다 더 클 뿐더러, 멤버 데이터에 접근하는 비용도 더 내야 한다. 또한 초기화가 필요한 가상 클래스로 부터 상속 받은 파생 클래스는 상속 계통의 거리와 상관 없이 가상 클래스를 초기화 해야 하는 의무를 맡아야한다.
이렇게 됨으로써 가독성은 더 떨어지고, 더 복잡해지는 상황이 초래하게 된다. 그렇기 때문에 대부분의 기본 가상 클래스는 데이터가 없고 함수들만 존재 하는 경우가 많이 있다.
하지만 이것도 설계의 한 방법이기에, 써야만 해야 할 때 써야 한다.
이것만은 잊지 말자!
1. 다중 상속을 단일 상속보다 복잡하다.
2. 가상 상속은 비용이 비싸다.
3. 가상 상속의 클래스는 멤버 데이터를 두지 않는게 편하다
관련링크
http://ikpil.tistory.com/trackback/344 <-- 이펙티브 2판, 아주 간략한 요약
http://tea815.com.ne.kr/cpp/594.htm <-- 일반적인 다중 상속
http://kldp.org/node/64575 <-- 결합으로 해결하는 방법
http://langdev.net/post/20 <-- 다중 상속에 대한 개념 이야기
http://axnoah.tistory.com/25 <-- 다중 상속의 단점을 지적한 이야기
http://whiteship.tistory.com/77 <-- 그림으로 흐름을 파악할수 있는 이야기
http://axnoah.tistory.com/24 <-- 다중 상속으로 격게 되는 복잡함
http://itking.tistory.com/499 <-- 다중 상속의 개념 이야기
http://eecs.tistory.com/entry/%EB%8B%A4%EC%A4%91%EC%83%81%EC%86%8D <-- 다중 상속 방법
http://ratmsma.tistory.com/entry/40026993362 <-- 역시 다중 상속에 대한 이야기
본론으로 들어와서, 나는 설계 단계에서 다중 상속 할까낭~ 하는 생각을 한적은 있었지만, 지금까지 다중 상속을 해서 코딩한적은 없다. 왜냐하면, 일단 설계단계 조차 난해하고, 조금 복잡해지는 경향이 있었다. 그래서 스스로가 "지금 여기에 꼭 필요한가?" 란 질문에 항상 "지금은 아니오" 라고 답하곤 했기 때문이다.
이번 항목 40의 제목처럼 "다중 상속은 심사숙고해서 사용하자" 로 이야기 하고 있다. 그렇다면 나는 이런 생각을 하곤 한다. "왜!? 무엇 때문에!?"
다중 상속을 왜 심사숙고 해야 하는가?
1. 함수의 모호성 : 코드로 보는게 이해가 더 빠르다.
함수 및 변수의 모호성을 보여주는 코드이다. 이 코드로 확인 할수 있듯이 어떤 Draw 를 호출했는지 .. 그 누구도 모르게 된다. 설령 인터페이스가 public 과 private 에 각각 Draw 가 있다 하더라도, C++ 컴파일러가 함수의 적법성 검사 할때, 모호성 에러를 발견하게 되어, 역시 컴파일 에러를 뱉어준다.
사실 이런것들은 사용자가 손쉽게 피해갈 수 있을것이다. 하지만 다음에 나오는 상황에서도 그럴까?
2. 멤버 변수의 모호성 : 코드로 보는게 이해가 더 빠르다.
이처럼 Base_var 에서 모호성이 발생한다. 이런 다이아몬드 상속 형태에선 ... 어떻게 손 쓸 방법이 없어진다. 이런 모호성을 없애기 위해, 참 편한 키워드 virtual 이 있다. 즉 가상 상속인데, 사용 법은 아래 코드를 첨부 했다.
이처럼 하면 된다.
언뜻 생각해 보면, 상속 받을 때 virtual 상속을 하면, 다 해결 될 듯한 생각도 든다. 이런 모호성도 없애줄 뿐만 아니라, 다중 상속을 보다 쉬울 수도 있을 것이다 ㅋ.
하지만 사람이 봐도 복잡한 이런 상속은 컴파일러 입장에서 봐도 처리하기 복잡하다. 이러한 처리 때문에, 가상 상속을 하는 클래스로 만든 객체의 크기는 일반 객체의 크기보다 더 클 뿐더러, 멤버 데이터에 접근하는 비용도 더 내야 한다. 또한 초기화가 필요한 가상 클래스로 부터 상속 받은 파생 클래스는 상속 계통의 거리와 상관 없이 가상 클래스를 초기화 해야 하는 의무를 맡아야한다.
이렇게 됨으로써 가독성은 더 떨어지고, 더 복잡해지는 상황이 초래하게 된다. 그렇기 때문에 대부분의 기본 가상 클래스는 데이터가 없고 함수들만 존재 하는 경우가 많이 있다.
하지만 이것도 설계의 한 방법이기에, 써야만 해야 할 때 써야 한다.
이것만은 잊지 말자!
1. 다중 상속을 단일 상속보다 복잡하다.
2. 가상 상속은 비용이 비싸다.
3. 가상 상속의 클래스는 멤버 데이터를 두지 않는게 편하다
관련링크
http://ikpil.tistory.com/trackback/344 <-- 이펙티브 2판, 아주 간략한 요약
http://tea815.com.ne.kr/cpp/594.htm <-- 일반적인 다중 상속
http://kldp.org/node/64575 <-- 결합으로 해결하는 방법
http://langdev.net/post/20 <-- 다중 상속에 대한 개념 이야기
http://axnoah.tistory.com/25 <-- 다중 상속의 단점을 지적한 이야기
http://whiteship.tistory.com/77 <-- 그림으로 흐름을 파악할수 있는 이야기
http://axnoah.tistory.com/24 <-- 다중 상속으로 격게 되는 복잡함
http://itking.tistory.com/499 <-- 다중 상속의 개념 이야기
http://eecs.tistory.com/entry/%EB%8B%A4%EC%A4%91%EC%83%81%EC%86%8D <-- 다중 상속 방법
http://ratmsma.tistory.com/entry/40026993362 <-- 역시 다중 상속에 대한 이야기
'책 정리 > Effective C++ 3판' 카테고리의 다른 글
항목 45: "호환되는 모든 타입"을 받아들이는 데는 멤버 함수 템플릿이 직방! (0) | 2008.07.31 |
---|---|
항목 44: 매개변수에 독립적인 코드는 템플릿으로부터 분리시키자. (0) | 2008.07.30 |
항목 43: 템플릿으로 만들어진 기본 클래스 안의 이름에 접근하는 방법을 알아 두자. (2) | 2008.07.28 |
항목 42: typename의 두가지 의미를 제대로 파악하자. (12) | 2008.07.25 |
항목 41: 템플릿 프로그래밍의 천릿길도 암시적 인터페이스와 컴파일 타임 다형성부터 (0) | 2008.07.25 |
항목 39 : private 상속은 심사숙고해서 구사하자 (0) | 2008.07.19 |
항목 38: "has-a(...는...를가짐)" 혹은 "is-implemented-in-terms-of(...는...를 써서 구현됨)"를 모형화 할 때는 객체 합성을 사용하자. (2) | 2008.07.18 |
항목 37: 어떤 함수에 대해서도 상속받은 기본 매개변수 값은 절대로 재정의 하지 말자. (0) | 2008.07.16 |
항목 36 : 상속받는 비가상 함수를 파생 클래스에서 재정의 하는 것은 절대 금물! (1) | 2008.07.14 |
항목 35: 가상 함수 대신 쓸 것들도 생각해 두는 자세를 시시때때로 길러 두자. (0) | 2008.07.14 |
최근댓글