실제로 C ++에서 개인 또는 보호 된 상속이 실제로 필요한 이유는 무엇입니까?

StackOverflow https://stackoverflow.com/questions/374399

문제

C ++에서는 기본 클래스로부터 개인을 물려 받고 싶은 경우를 생각할 수 없습니다.

class Base;
class Derived1 : private Base;
class Derived2 : protected Base;

정말 유용합니까?

도움이 되었습니까?

해결책

기본 클래스의 일부 구성원에게 액세스 할 수 있지만 클래스 인터페이스에 노출하지 않고 유용합니다. 개인 상속은 또한 일종의 구성으로 볼 수 있습니다. C ++ FAQ- 라이트 이 진술을 설명하기 위해 다음 예제를 제시합니다

class Engine {
 public:
   Engine(int numCylinders);
   void start();                 // Starts this Engine
};

class Car {
  public:
    Car() : e_(8) { }             // Initializes this Car with 8 cylinders
    void start() { e_.start(); }  // Start this Car by starting its Engine
  private:
    Engine e_;                    // Car has-a Engine
};

동일한 의미를 얻으려면 자동차 수업을 다음과 같이 쓸 수도 있습니다.

class Car : private Engine {    // Car has-a Engine
 public:
   Car() : Engine(8) { }         // Initializes this Car with 8 cylinders
   using Engine::start;          // Start this Car by starting its Engine
}; 

그러나 이러한 행동 방식에는 몇 가지 단점이 있습니다.

  • 당신의 의도는 훨씬 명확하지 않습니다
  • 그것은 학대적인 다중 상속으로 이어질 수 있습니다
  • 보호 된 멤버에 액세스 할 수 있으므로 엔진 클래스의 캡슐화를 중단합니다.
  • 엔진 가상 메소드를 무시할 수 있습니다. 목표는 단순한 구성이라면 원하지 않는 것입니다.

다른 팁

개인은 상당히 몇 가지 상황에서 유용 할 수 있습니다. 그들 중 하나만 정책입니다.

부분 클래스 템플릿 전문화 가이 설계 문제에 대한 답변입니까?.

유용한 또 다른 경우는 복사 및 할당을 금지하는 것입니다.

struct noncopyable {
    private:
    noncopyable(noncopyable const&);
    noncopyable & operator=(noncopyable const&);
};

class my_noncopyable_type : noncopyable {
    // ...
};

우리는 사용자가 유형의 포인터를 가지고 있기를 원하지 않기 때문에 noncopyable* 우리의 대상으로, 우리는 개인적으로 파생됩니다. 이는 비정치 불가능뿐만 아니라 다른 많은 클래스도 중요합니다 (정책이 가장 일반적입니다).

공개 상속 모델은 A입니다.
비공개 상속 모델은 구현 된 내용입니다.
격리 모델은 a has-a이며, 이는 IS- 구현과 동일합니다.

주제에 대한 SURTER. 그는 구현 세부 정보를 위해 비공개 상속을 선택할 때 설명합니다.

예를 들어, 구현을 재사용하려는 경우 클래스의 인터페이스는 아니고 가상 함수를 무시하지 않습니다.

개인 상속은 대부분 잘못된 이유로 사용됩니다. 사람들은 이전 답변에 표시된대로 IS- 구현에 사용하지만, 내 경험상 수업에서 물려받지 않고 사본을 유지하는 것이 항상 더 깨끗합니다. 또 다른 초기 답변 인 Cbigarray에 관한 답은이 패턴의 완벽한 예를 제공합니다.

나는 "보호 된"의 과도한 사용으로 인해 HAS-A가 작동하지 않는 경우가있을 수 있지만, 새로운 클래스를 깨는 것보다 깨진 클래스를 고치는 것이 좋습니다.

나는 한 지점이나 다른 시점에서 개인 및 보호 된 상속을 모두 사용했습니다.

사적 내유는 기본 클래스의 행동을 갖기를 원한 다음 해당 기능을 무시할 수있는 경우 유용하지만 전 세계가 그것을 알고 사용하기를 원하지 않습니다. 함수를 해당 인터페이스로 리턴하여 개인적으로 파생 된 클래스의 인터페이스를 사용할 수 있습니다. 개인 인터페이스를 사용하여 스스로 등록 할 수 있으므로 콜백을 듣도록 스스로 등록 할 수있는 경우에도 유용합니다.

보호 된 유전은 다른 클래스에서 유용한 기능을 도출하는 기본 클래스가있을 때 특히 유용하지만 파생 클래스 만 사용할 수 있기를 원합니다.

한 번은이 데이터 구조를 클래스로 구현했습니다.

  • 링크 된 목록
  • 제네릭 어레이 (초록)
  • 간단한 배열 (일반 어레이에서 상속)
  • 큰 배열 (일반 배열에서 상속)

큰 배열의 인터페이스는 배열처럼 보이지만 실제로는 고정 된 크기의 간단한 배열의 링크 된 목록이었습니다. 그래서 나는 다음과 같이 선언했습니다.

template <typename T>
class CBigArray : public IArray, private CLnkList {
    // ...
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top