private 계승은 정말 소용없나요??

3157 단어 물려받다private
private 계승, effective C++를 보기 전에 나는 이전 코드에서 이 메커니즘을 사용하지 않았음을 발견했지만 진지하게 회상하면 아직도 그림자가 있다.
대다수의 사람들은private 계승은 소용없다고 생각하지만, 사실은 그렇지 않다. 어떤 경우에도 그것은 당신에게 놀라움을 줄 수도 있다.
자, 본론으로 돌아가자면 앞서 수차례 언급한 바와 같이 퍼블릭 계승은'isa'의 관계를 나타낸다. 즉, 모든derived 대상 D는base 대상이므로 베이스 대상에서의 모든 조작은derived 대상에게 실시할 수 있다.
예를 들면 다음과 같습니다.
class Person{....};
class Student::public Person{...};

Person p;
Student s;

void eat(Person *p);
void study(Student &s);

eat(s);// Person , Student 。
eat(p); 

그러나 상술한 퍼블릭 계승을private 계승으로 바꾸면 eat(s) 호출이 실패합니다.
그렇다면private 계승이 도대체 무엇을 의미하는지 먼저 직관적으로 말하자면 상술한 Student 대상이 Person 대상으로 전환되지 않았고 그 다음에
private에서 계승된 모든 Base의 구성원은Derived에서 private 속성입니다. (원래 Base 클래스의 속성이public이든 아니든
protected).
가장 중요한 점은private 계승은 "is implemented as..."(어떤 물건으로 이루어진다)Derived류는 계승일 뿐이라는 것을 의미한다
베이스 클래스의 속성은 인터페이스를 계승하지 않습니다.이것은 실현 차원상의 일이다.
특히 복합적 의미도 "is implemented as..."(어떤 물건으로 이루어진다) 이것은 마치 그'private 계승이 무용하다는 것을 증명하는 것 같다.
이 두 자의 균형은 매우 간단하다. 둘 다 가능한 상황에서private 계승이 아니라private 계승을 선택한다. 특수한 경우를 제외하고 다음 몇 가지는
하나의 예는 바로 양자의 차이를 이야기하는 데 쓰인다.
가정:
현재 클래스 Widget의 상태, 예를 들어 함수 호출 횟수 등을 통계하기 위해 클래스 Timer를 정의해야 합니다. 이런 기능을 실현하기 위해서는 클래스가 필요합니다.
정의는 다음과 같습니다.
class Timer{
public: explicit Timer(int ticks);
virtual ontick() const;// ,
...
};

분명히, Widget 클래스에서 Timer 클래스의 대상을 사용해야 하는데,public 계승을 사용하는 것은 종속 관계가 없기 때문에 적합하지 않다.그럼 프라이빗 상속이 생각나네.
그리고 ontick 함수를 재정의했습니다.
class Widget:public Timer
{
private:
virtual ontick() const;
...
};

주: 여기에서 ontick 함수를private 부분에 정의한 것은 클래스의 대상이 ontick 함수를 호출할 수 있다고 오인하지 않도록 하기 위해서입니다. (이 함수는private입니다. 어떤 위치에 정의되었든지.)
분명히 이것은 실행할 수 있는 것이다. 그러면 복합을 사용하면 안 되는 것입니까?Widget 내부에서 Timer 클래스를 상속하기 위한 값이 클래스 자체에 속하는 클래스를 정의하기만 하면 됩니다. 즉,
class Widget
{
    private:
        class TimerManager:public Timer
        {
            public:
                void ontick() const;
                ...
        };
        TimerManager timer;
        ...

};

이 디자인은 상술한 private 계승보다 이해하기 쉽다.그리고 하나 더 흥미로운 것은 Widget이 Base class가 되려는 클래스라고 가정하면
다른 클래스가widget을 계승한다는 말입니다.private 계승을 사용하면,widget의derived 클래스가ontick 함수를 수정할 수 있습니다.
그것의 기류인 허함수이기도 하다.
단, 이 함수에서 Timer의virtual 함수를 다시 쓸 필요가 있다면,private 계승을 선택하는 것이 필수적입니다.
그 다음으로private 계승이라면Widget 클래스를 정의할 때 Timer 클래스는 반드시 볼 수 있어야 한다. 즉,'Timer.h'라는 글자가 포함되어야 한다.
그러나 복합에서 Pointer to Implement(pImpl) 기술을 충분히 사용할 수 있다.Widget 클래스에서 Timer의 바늘을 정의하면 된다.
Timer의 설명만 있으면 컴파일의 결합성을 낮출 수 있습니다.
그러나 다음과 같은 극단적인 예: 계승할 클래스는 공류이다
class Empty{};
class HasAInt
{
    private:
        int a;
        Empty e;
};

위의sizeof(hasAInt)>sizeof(int);빈 클래스가 차지하는 공간에 대한 설명은http://blog.csdn.net/xuqingict/article/details/24433311
하지만 private 계승을 사용합니다.C++컴파일러는'공백 기류 최적화'라는 원칙이 있습니다. 그렇습니다. sizeof(hasAInt)==sizeof(int);
(주: 이 원칙은 단일 계승에만 유효하다) 이것은 대상의 사이즈에 대한 요구가 매우 엄격한 절차에 있어서 매우 중요할 수 있다.
요약하자면private 계승은 쓸모가 없는 것이 아니지만 복합적으로 같은 기능을 실현할 수 있다면 존경하고 멀리하라.

좋은 웹페이지 즐겨찾기