2014-12-16 1 views
2

스마트 포인터가 ROOT 개체 소유권 체계와 함께 살아갈 것으로 예상되는 방식을 이해하려고합니다. 나는 아주 멀리 갈 필요가 없었다. 이것 좀 봐CERN ROOT의 개체 소유권 및 C++ 11 스마트 포인터

#include <iostream> 
#include <memory> 
#include "TH1F.h" 
#include "TFile.h" 

int main() 
{ 
    TFile f("out.root", "recreate"); 
    f.cd(); 
    std::unique_ptr<TH1F> h {new TH1F("h", "h", 100, -5, 5)}; 
    h->FillRandom("gaus", 10000); 
    h->Write(); 
    f.Close(); 

    return 0; 
} 

고유 포인터로 처리되는 막대 그래프는 현재 gDirectory에서 소유하고있었습니다. 내 프로그램을 종료하기 전에 나는 정중하게 파일을 닫았 기 때문에 히스토그램은 ROOT 메모리 관리 사람에 의해 파괴되었습니다. 이제 main()의 끝에서 내 포인터가 범위를 벗어나 리소스를 해제해야하지만 이미 해제되었습니다!

ROOT 개체 소유권/메모리 관리가 C++ 11 스마트 포인터와 함께 살 것으로 예상되는 방법에 대한 리소스를 찾지 못했습니다.

내 질문에, ROOT 개체 관리가 켜져있는 코드에서 스마트 포인터를 사용합니까? HENP 실험에서 C++ 11 스마트 포인터를 사용합니까?

+1

ROOT가 정말로 소유권을 처리하는 경우 왜 이것을 unique_ptr과 함께 사용 하시겠습니까? 나는 ROOT의이 특정 부분이 스마트 포인터 (또는 똑똑한 것)와 함께 작동하도록 설계되지 않았다고 생각한다. – juanchopanza

+0

ROOT 객체를 처리하는 코드에서 스마트 포인터를 사용하는 것에 대한 다른 실험 '/ 사용자'지침은 무엇인지 이해하고 싶다. . 현대의 C++ 코드가 알몸 포인터를 제거 할 것으로 예상되면 프로그래머 코드에 더 많은 스마트 포인터가 표시 될 것으로 예상됩니다. 그래서 ROOT 객체를 처리하기 위해 스마트 포인터의 사용을 금지해야합니까? ROOT 개체 관리를 해제 하시겠습니까? ROOT의 다른 계획이이 문제를 해결할 계획입니까? – Mustafa

+0

물론, 필요할 때만 스마트 포인터를 사용해야합니다. 이미 무언가가 동적으로 할당 된 객체를 소유하고있는 경우 소유주가 어떤 종류의 해제 메커니즘을 가지고 있지 않으면 소유권을 획득하려고 시도 할 수 없습니다. 또한이 대부분은 근대 이전 시대의 "설계"된 것임을 주목하십시오. 필자가 보아온 한 가지 접근 방법은 전역 객체와 이상한 규칙에 의존하지 않는 더 현대적인 인터페이스 뒤에 모든 메모리 관리를 숨기는 것입니다. – juanchopanza

답변

0

글쎄, 나는 unique_ptr과 ROOT를 행복하게 결혼하게 만들 것이라고 생각 하겠지만, 사용자 정의 deleter를 사용해야합니다. 사용자 정의 Deleter가에서

그렇지 않으면 더 복잡한 체계를 고안 할 수

auto deleter = [](TH1F* p) { key = FindKey(p->Name); if (key) delete p }; 

std::unique_ptr<TH1F, decltype(deleter)> h{new TH1F("h", "h", 100, -5, 5), deleter}; 

어떤 조합에게 그것 (의사의) 같은

뭔가를하지 않습니다, 경우 히스토그램 아직 살아 확인하고 삭제해야 ..

+0

그것이 삭제되었는지 어떻게 알 수 있습니까? – juanchopanza

+0

@juanchopanza IIRC (오래전에 ROOT를 다루었습니다.) 제안 된대로 이름을 키로 확인해야합니다. key가 NULL이 아닌 경우, 현재 컨텍스트에 있고 삭제 될 수 있습니다. –

+0

이름으로 확인할 수는 있지만 이름을 알아야합니다. 'p>가 이미 삭제 되었다면'p-> Name'을 호출하는 것은 분명히 작동하지 않습니다. 'p'가 삭제되면, 이것은 단지 실패합니다. – Chris

2

TH1::AddDirectory(false)을 사용하는 경우 히스토그램을 관리하므로 스마트 포인터를 사용하는 데 문제가 없습니다.

+0

내 질문은 어떻게 스마트 포인터와 함께 ** ROOT 개체 소유권 ** 라이브 **를 만드는 것이었다. ROOT 개체 관리를 해제하는 방법이 아닙니다. – Mustafa

1

std::unique_ptr을 사용하는 경우이 개체를 개체의 유일한 소유자가되고 싶습니다.

#include <iostream> 
#include <memory> 
#include "TH1F.h" 
#include "TFile.h" 

int main() 
{ 
    TFile f("out.root", "recreate"); 
    f.cd(); 
    std::unique_ptr<TH1F> h {new TH1F("h", "h", 100, -5, 5)}; 
    h->SetDirectory(0); 
    h->FillRandom("gaus", 10000); 
    h->Write(); 
    f.Close(); 

    return 0; 
} 

당신은 여전히 ​​다른 모든 히스토그램에 대한 ROOT의 객체 소유권을 가지고이 길을,하지만 당신은이 일을 직접 소유 할 수 있습니다 : 당신은 h->SetDirectory 하나의 히스토그램에 대한 ROOT의 객체 소유권을 해제 할 수 있습니다.

관련 문제