Hi, I read the “Object ownership” section of the ROOT users guide, and it says:
I’m using TGraph::Fit, which returns a TFitResultPtr holding (but, by reading the destructor code, not owning) a pointer to a TFitResult. I’m wondering if I own the TFitResult. I have this concern because I’m fitting in a cycle, now I’m doing something like
TGraph graph(...);
unique_ptr<TFitResult> fit {&*graph.Fit(...)};
I assumed to own it because it makes sense: otherwise a TGraph would have to store a vector of TFitResults just to delete the arbitrarily many fit results generated.
i.e. storing the TFitResultPtr on the stack does not, so the object is in some way owned and deleted by ROOT. I thought not because the destructor of TFitResultPtr is
////////////////////////////////////////////////////////////////////////////////
/// Destructor. Delete the contained TFitResult pointer if needed
/// if ( fPointer != 0)
/// delete fPointer;
TFitResultPtr::~TFitResultPtr()
{
}
where fPointer is a std::shared_ptr, so should not be automatically deleted in any way.
it’s explained in the documentation, specifically the section about the TFitResult:
If the option “S” is instead used, TFitResultPtr contains the TFitResult and behaves as a smart pointer to it.
Note, in particular, that the TFitResultPtr is an object and not a pointer, in the same way that a unique_ptr is not a pointer (that you can e.g. delete). You should not wrap it in anything, but just keep it on the stack.
“Behaves as a smart pointer” is not clear to me on the policy for deleting the object. Since in the code TFitResultPtr does not contain a TFitResult but a std::shared_ptr<TFitResult>, i.e. a pointer handler which does not call delete on its pointer upon destruction, and ~TFitResultPtr is defined explicitly to do nothing, it is not obvious that I do not have to delete the pointer contained in the TFitResultPtr, provided I do not trust that section of the manual because in this case it appears more efficient to relinquish property of the TFitResult to the user.
Anyway, as I said, I was wrong, and I don’t have to delete &*result_ptr.
I was wrapping the TFitResult, not the TFitResultPtr.
EDIT: I was wrong, shared_ptr does delete its pointer.
This means that the TFitResultPtr will take care of deleting the FitResult it points to. In that sense, it behaves like std::unique_ptr and std::shared_ptr. (As you saw yourself, it is actually implemented using a shared_ptr, so all is taken care of.)
Do you think that the documentation of the TFitResultPtr needs to be improved?