3

我试图了解智能指针如何与 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 智能指针吗?

4

3 回答 3

2

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

于 2014-12-17T15:23:19.807 回答
2

如果您正在使用std::unique_ptr,您真的希望它成为该对象的唯一所有者。您可以使用以下命令关闭一个直方图的 ROOT 对象所有权h->SetDirectory

#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 对象所有权,但您可以自己拥有这个。

于 2016-02-14T23:52:56.127 回答
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};

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

于 2014-12-16T21:40:13.130 回答