2017-03-19 2 views
3

나는이 slides을 확인하지만 여전히하지 않았다 :왜 QuantLib에서 Handle 클래스를 도입 했습니까?

template <class Type> 
    class Handle { 
     protected: 
     class Link : public Observable, public Observer { 
      public: 
      explicit Link(const shared_ptr<Type>& h = 
             shared_ptr<Type>()); 
      void linkTo(const shared_ptr<Type>&); 
      bool empty() const; 
      void update() { notifyObservers(); } 
      private: 
      shared_ptr<Type> h_; 
     }; 
     boost::shared_ptr<Link<Type> > link_; 
     public: 
     explicit Handle(const shared_ptr<Type>& h = 
             shared_ptr<Type>()); 
     const shared_ptr<Type>& operator->() const; 
     const shared_ptr<Type>& operator*() const; 
     bool empty() const; 
     operator boost::shared_ptr<Observable>() const; 
    }; 

    template <class Type> 
    class RelinkableHandle : public Handle<Type> { 
     public: 
     explicit RelinkableHandle(const shared_ptr<Type>& h = 
             shared_ptr<Type>()); 
     void linkTo(const boost::shared_ptr<Type>&); 
    }; 

사람이 더 나은 예를 들어 줄 수 :

소스 코드에서
1) what problem does Handle sovled? 

2) what is the benefit to add the Handle class? 

, 나는 어떤 단서 중 하나를 얻을 수 없다?

감사합니다.

답변

3

짧은 대답 : Handle 클래스는 포인터에 대한 스마트 포인터입니다.

무엇이 좋나요? 예를 들어 Euribor6M과 같은 이자율 색인의 인스턴스를 예로 들어 보겠습니다. 현재, 생성자는 미래의 고정을 예측하는 yield term 구조를 처리합니다. 대신 shared_ptr을 사용하면 어떻게 될까요?

유스 케이스를 살펴 보겠습니다. 경고 : 너무 많은 코드를 작성하지 않도록 단순화하고 있지만 합법적 인 사용 사례입니다. 이제 우리가 시작 평면 곡선 인덱스를 초기화 가정 해 봅시다 :

shared_ptr<SimpleQuote> r = make_shared<SimpleQuote>(0.01); 
shared_ptr<YieldTermStructure> curve = 
    make_shared<FlatForward>(today, r, Actual360()); 

shared_ptr<InterestRateIndex> index = make_shared<Euribor6M>(curve); 

는 (실제 사용 사례에서, curve 인용 비율의 집합에 부트 스트랩 유리 보 곡선이 될 것이다). index의 생성자는 전달 된 shared_ptr<YieldTermStructure>의 복사본을 가져 와서 복사본을 만들어 데이터 멤버로 저장합니다. 구축이 끝나면 인덱스를 다른 도구 (스왑, 변동 금리 채권 등)에 전달합니다.

금리는 우리가 여전히 r 인용의 보류를 변경하고, 주어진 경우

, 우리의 클라이언트 코드가 r 이후

r->setValue(0.015); 

쓸 수 및 curve 공유 포인터는,이 또한의 속도를 변경합니다 인덱스 내부의 곡선 복사본 (curve 및 그 사본은 index 안에 있으므로 동일한 객체를 가리 킵니다). 결과적으로 인덱스 고정 및 종속 변수 값도 변경됩니다.

그러나 다른 커브를 사용하기를 원한다고 가정 해 봅시다. 이 경우, 우리는 대신 평면 하나의 보간 곡선으로 전환 할 수 있습니다 : 실제 경우 (

vector<Date> dates = ... ; 
vector<Rate> rates = ... ; 
shared_ptr<YieldTermStructure> curve2 = 
    make_shared<ZeroCurve>(dates, rates, Actual360()); 

, 우리는 따옴표의 다른 세트에 곡선을 부트 스트랩하거나 다른 방법을 사용할 수 있습니다 모델 요금에).

curve2으로 시작한다고 어떻게 말할 수 있습니까? shared_ptr을 사용할 수는 없습니다.

curve = curve2; 

curve는 보간 곡선을 가리 키도록 원인이되지만, 는 이전 가리키는 계속됩니다 curveindex 내부의 복사 : 우리는 말할 경우에도 마찬가지입니다. 이것은 shared_ptr의 문제는 아니지만 일반적으로 포인터가 있습니다. 어떻게 해결합니까? 간접 참조의 또 다른 계층을 추가합니다. 원시 포인터를 사용한다면, 포인터에 대한 포인터를 사용하기 시작할 것입니다.우리 코드에서 Handle은 똑같은 일을합니다 : shared_ptr을 가리키며 같은 핸들의 두 복사본이 같은 shared_ptr을 가리 키도록 구현됩니다. 이 방법, 당신이 쓰는 경우 :

h.linkTo(curve2); 

을 모두 index 안에 당신이 잡아 핸들 및 사본 새로운 곡선을 가리 킵니다 :

shared_ptr<SimpleQuote> r = make_shared<SimpleQuote>(0.01); 
shared_ptr<YieldTermStructure> curve = 
    make_shared<FlatForward>(today, r, Actual360()); 
RelinkableHandle<YieldTermStructure> h(curve); 

shared_ptr<InterestRateIndex> index = make_shared<Euribor6M>(h); 

는 나중에 쓸 수 있습니다.

RelinkableHandleHandle의 차이점은 이전에 linkTo으로 전화 할 수 있습니다. 아이디어는 RelinkableHandle을 인스턴스화하고 복사본을 단지 Handle으로 전달하므로 아무 것도 지정할 수 없으며 (const을 사용하면 const는 간단한 복사본으로 버려 질 수 있기 때문에) 사용할 수 없습니다.

+0

루이지 귀하의 명확한 설명에 감사드립니다. – camino

+0

설명해 주셔서 감사합니다. 이것에 대한 또 하나의 질문입니다. 클래스 링크는 무엇을하고 링크의 생성자에 전달 된 공유 포인터에 대해 어떻게 생각해야합니까? – user1559897

+0

링크의'shared_ptr '은 현재 가리키는 객체입니다. 'Link' 클래스는 그 위에 관찰 가능성을 추가하여 뾰족한 객체가 변경 될 때 알림을 얻습니다. –

관련 문제