-
Notifications
You must be signed in to change notification settings - Fork 97
Description
As C++ Core guidelines (I.11) suggests:
Never transfer ownership by a raw pointer (T*) or reference
Problem:
For example, the event header, which is denoted as fEvtHeader
, is owned by class FairRun
as it's deleted in the deconstructor.
But at the same time, there is a method, which can reseat the fEvtHeader pointer to another user-defined object:
Line 79 in 8501262
void SetEventHeader(FairEventHeader* EvHeader) { fEvtHeader = EvHeader; } |
Here we have two problems:
- If fEvtheader is already pointing to an existing event header, that existing one won't get deleted in the end and hence we have a memory leak.
- Users have absolutely no idea whether they need to delete the pointer they passed to the method or not. If they don't go deep into the source files, the default is to delete the pointer because it's passed as a raw pointer.
Suggestions:
-
Whenever a class owns an object, encapsulate the pointer into
std::unique_ptr<>
. ( this also increases exception safety. ) -
When a class need to consume an object, make the parameter as the type
std::unique_ptr<>
As in the case of the example, following code is much better:void SetEventHeader(std::unique_ptr<FairEventHeader> NewEvHeader) { fEvtHeader = std::move(NewEvHeader); // reseating the unique_ptr }
With this, the two problem mentioned above are solved. First, old event header get deleted automatically. Second, User knows this is an ownership transferring and he doesn't need to delete the pointer created by him.
For the user, all he needs to do is:
auto eventHeader = std::unique_ptr<R3BEventHeader>(new R3BEventHeader()); FairRun::Instance()->SetEventHeader(std::move(eventHeader)); // ownership transferring.