CERN ROOT的对象所有权和C ++ 11智能指针

时间:2014-12-16 19:01:42

标签: c++ c++11 root-framework

我试图了解智能指针如何与ROOT对象所有权方案一起使用。我没有走得太远。看看这个

#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智能指针吗?

3 个答案:

答案 0 :(得分:2)

如果你使用TH1::AddDirectory(false),你将管理直方图,然后使用智能指针就没有问题了。

答案 1 :(得分:1)

如果您使用的是std::unique_ptr,那么您确实希望它成为该对象的唯一所有者。您可以使用h->SetDirectory

关闭一个直方图的ROOT对象所有权
#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对象所有权,但你可以自己拥有这个直方图。

答案 2 :(得分:0)

好吧,我猜想让unique_ptr和ROOT幸福结婚,你必须使用自定义删除器。

在自定义删除器中,您必须检查直方图是否仍然存在并将其删除,否则将其删除

像(伪代码)

之类的东西
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};

可以设计更复杂的方案......