[c++] C ++에서 다중 상속을 피하는 이유는 무엇입니까?



6 Answers

Bjarne Stroustrup과인터뷰에서 :

사람들은 다중 상속을 필요로하지 않는다고 말합니다. 다중 상속으로 할 수있는 일은 단일 상속으로도 할 수 있기 때문입니다. 방금 언급 한 위임 트릭을 사용합니다. 또한 상속을 전혀 필요로하지 않습니다. 단일 상속으로 수행하는 작업은 상속없이 클래스를 통해 전달할 수 있기 때문에 상속이 필요하지 않습니다. 실제로 포인터와 데이터 구조로 모든 작업을 수행 할 수 있으므로 클래스도 필요하지 않습니다. 그런데 왜 그걸하고 싶니? 언어 시설을 이용하는 것이 언제 편리합니까? 해결 방법을 언제 선호합니까? 다중 상속이 유용한 경우를 보았고, 다중 상속이 매우 복잡한 경우도 보았습니다. 일반적으로 언어에서 제공하는 기능을 사용하여 대안을 취하는 것을 선호합니다.

Question

다중 상속을 사용하는 것이 좋은 개념입니까, 아니면 대신 다른 작업을 수행 할 수 있습니까?




다이아몬드 패턴 외에도 다중 상속은 객체 모델을 이해하기 어렵게 만들고 유지 비용을 증가시킵니다.

구성은 본질적으로 이해하기 쉽고, 이해하고, 설명하기 쉽습니다. 코드를 작성하는 것은 지루할 수 있지만, 좋은 IDE (Visual Studio로 작업 한 지 수 년이되었지만, 확실히 Java IDE에는 모두 멋진 단축키 자동화 도구가 있습니다)는 장애물을 극복해야합니다.

또한 유지 보수면에서 비 문자 상속 인스턴스에서도 "다이아몬드 문제"가 발생합니다. 예를 들어, A와 B가 있고 C 클래스를 모두 확장하면 A는 오렌지 주스를 만드는 'makeJuice'방법을 사용하며 석회로 오렌지 주스를 만드는 방법을 확장합니다. 디자이너가 ' B '는 전류를 생성하고 생성하는'makeJuice '방법을 추가합니까? 'A'와 'B'는 지금 "부모"와 호환 될 수 있지만, 그렇다고해서 항상 그렇게 될 것은 아닙니다.

전반적으로 상속을 피하기위한 경향의 극대화, 특히 다중 상속은 건전합니다. 모든 격언에는 예외가 있지만 코드를 작성하는 예외를 가리키는 깜박이는 녹색 네온 사인이 있는지 확인해야합니다 (뇌가 열리면 상속 나무가 보이기 때문에 언제든지 그린 네온이 깜박입니다) sign), 그리고 당신은 모든 것이 한 번씩 의미가 있는지 확인해야합니다.




모든 프로그래밍 언어는 장단점이있는 객체 지향 프로그래밍의 처리 방법이 약간 다릅니다. C ++의 버전은 성능에 중점을두고 있으며 잘못된 코드를 작성하기가 쉽지 않은 부수적 인 단점이 있습니다. 이는 다중 상속에 해당합니다. 따라서 프로그래머가이 기능을 사용하지 못하도록하는 경향이 있습니다.

다른 사람들은 다중 상속이 어째서 좋지 않은가에 대한 문제를 다루었습니다. 그러나 우리는 그것이 안전하지 않기 때문에 그것을 피하는 이유가 더 많거나 적은 것을 암시하는 꽤 많은 의견을 보았습니다. 네, 그렇습니다.

C ++에서 흔히있는 것처럼, 기본 지침을 따르면 "어깨 너머로"보지 않아도 안전하게 사용할 수 있습니다. 핵심 아이디어는 "혼합"이라고 불리는 특별한 종류의 클래스 정의를 구별하는 것입니다. 클래스는 모든 멤버 함수가 가상 (또는 순수 가상) 인 경우 혼합입니다. 그런 다음 하나의 메인 클래스와 원하는만큼 많은 "믹스 인"을 상속받을 수 있지만 "가상"키워드로 믹스 인을 상속해야합니다. 예

class CounterMixin {
    int count;
public:
    CounterMixin() : count( 0 ) {}
    virtual ~CounterMixin() {}
    virtual void increment() { count += 1; }
    virtual int getCount() { return count; }
};

class Foo : public Bar, virtual public CounterMixin { ..... };

제 제안은 클래스를 믹스 인 클래스로 사용하려는 경우 명명 규칙을 사용하여 코드를 읽는 사람이 무슨 일이 일어나고 있는지를 쉽게 확인하고 기본 가이드 라인의 규칙에 따라 놀고 있는지 확인하는 것입니다. . 또한 가상베이스 클래스의 작동 방식 때문에 믹스 인에 기본 생성자가있는 경우 훨씬 더 효율적으로 작동합니다. 모든 소멸자를 가상으로 만드는 것을 잊지 마십시오.

여기서 "믹스 인"이라는 단어를 사용하는 것은 매개 변수화 된 템플릿 클래스와 다릅니다 (좋은 설명을 보려면 이 링크 참조).하지만 용어의 정당한 사용이라고 생각합니다.

이제는 이것이 다중 상속을 안전하게 사용하는 유일한 방법이라는 인상을주고 싶지 않습니다. 확인하기 쉬운 방법 중 하나입니다.




우리는 에펠을 사용합니다. 우리는 뛰어난 MI를 가지고 있습니다. 걱정 마. 문제 없음. 쉽게 관리 할 수 ​​있습니다. MI를 사용하지 않는 경우가 있습니다. 그러나 사람들이 깨닫는 것보다 더 유용합니다 : A) 잘 관리하지 못하는 위험한 언어 - 또는 - B) 그들이 수년간 MI에서 어떻게 일했는지에 만족함 - 또는 - C) 다른 이유들 ( 목록이 너무 많아서 나는 확실히 확신합니다 - 위의 답변을보십시오).

우리에게는 Eiffel을 사용하여 MI가 다른 것보다 자연 스러우며 도구 상자에 다른 훌륭한 도구가 있습니다. 솔직히, 우리는 에펠을 사용하는 사람이 아무도 없다는 사실에 전혀 관심이 없습니다. 걱정 마. 우리는 우리가 가지고있는 것에 만족하며 당신에게 한 번 보라고 권합니다.

찾고있는 동안 : 무효화 및 Null 포인터 참조 해제의 제거에 특히주의하십시오. 우리가 모두 MI에서 춤을 추는 동안, 당신의 조언은 길을 잃고 있습니다! :-)




상속에 우선하여 composition을 사용할 수 있습니다.

일반적인 느낌은 구성이 더 좋고, 매우 잘 논의 된 것입니다.




다중 상속을 피할 수는 없지만 '다이아몬드 문제'( http://en.wikipedia.org/wiki/Diamond_problem )와 같이 발생할 수있는 문제를 알아야하며 사용자에게 주어진 힘을주의 깊게 다루어야합니다 , 당신은 모든 힘으로해야한다.




w : 다중 상속 참조.

다중 상속은 비판을 받았으며, 따라서 여러 언어로 구현되지 않았습니다. 비판에는 다음이 포함됩니다.

  • 복잡성 증가
  • 시맨틱 모호성은 종종 다이아몬드 문제 로 요약됩니다.
  • 단일 클래스에서 여러 번 명시 적으로 상속 할 수 없음
  • 상속의 클래스 의미를 변경하는 순서.

C ++ / Java 스타일 생성자를 사용하는 언어의 다중 상속은 생성자 및 생성자 체인의 상속 문제를 악화 시키므로 이러한 언어에서 유지 관리 및 확장 성 문제가 발생합니다. 커스터마이징 패러다임 (constructor chaining paradigm) 하에서는 매우 다양한 구성 메소드를 사용하여 상속 관계에있는 객체를 구현하기가 어렵습니다.

COM 및 Java 인터페이스와 같은 인터페이스 (순수 추상 클래스)를 사용하여이를 해결하는 현대적인 방법.

나는 이것 대신에 다른 일을 할 수 있습니까?

그래 넌 할수있어. 나는 GoF 에서 훔칠거야.

  • 구현이 아닌 인터페이스에 프로그램하십시오.
  • 상속에 대한 컴포지션 선호


Related