Hi Alex,
most MITK derive from "ITK", so I suggest to make familiar with itk::LightObject/Object and itk::SmartPointer in the ITK documentation, which will basically answer all your questions. :-) It works because the reference counter of the "reference counting smart pointer" is not part of the smart pointer but of the object. The actual call to "Add()" does not increase the ref counter because it takes a raw pointer. When the data storage decides in "Add()" to also own the passed object, it stores it / casts it to another smart pointer, which will correctly increase the ref counter of the object. If we would change the signature of "Add()" to take a smart pointer, the passed temporary (C++ copy-by-value semantics) would temporarilly *additionally* increase the reference counter and decrease it at the end of "Add()" which would be unneccessary code to generate. Best, Stefan ________________________________ Von: Alex Melville <amelv...@umich.edu> Gesendet: Dienstag, 28. Juli 2020 17:09 An: mitk-users@lists.sourceforge.net Betreff: [mitk-users] Smart pointers and DataStrorage ownership question Hello, I had a question about one of the examples given in the github repo, I notice that in this example: https://github.com/MITK/MITK/blob/4ef5c654cab87f37d1a5a6c26a22db99a2b324d8/Examples/Plugins/org.mitk.example.gui.imaging/src/internal/isosurface/QmitkIsoSurface.cpp#L123 (comments added by me) mitk::DataNode::Pointer surfaceNode = mitk::DataNode::New(); // creates a smart pointer surfaceNode->SetData(filter->GetOutput()); int layer = 0; ++m_SurfaceCounter; std::ostringstream buffer; buffer << m_SurfaceCounter; std::string surfaceNodeName = "Surface " + buffer.str(); node->GetIntProperty("layer", layer); surfaceNode->SetIntProperty("layer", layer + 1); surfaceNode->SetProperty("Surface", mitk::BoolProperty::New(true)); surfaceNode->SetProperty("name", mitk::StringProperty::New(surfaceNodeName)); this->GetDataStorage()->Add(surfaceNode, node); // Add takes in a DataNode*, not a smart pointer I was thinking about the scoping involved here, since surfaceNode is a local variable in the function, wouldn't the destructor be called at the end of the function, causing the DataNode to be deallocated (without the data storage's knowledge)? This example works so I figure I must be missing something here, - Does the implicit conversion to DataNode* in the call to this->GetDataStorage()->Add() increment the reference counter in the DataNode? - Does DataStorage::Add() make a copy of the node? - Or is something else going on? I notice that the constructor of mitk::DataNode is protected, so it might be required to always create a smart pointer, and this is just boilerplate / accepted standard code to work around that. It seems like some methods use smart pointers in MITK, and some don't. Other questions: - Is there a reason why DataStorage::Add() doesn't take in a smart pointer as a parameter? - DataNode::New() seems to literally just call DataNode's constructor, then wraps it in a smart pointer, is there a reason why DataNode's constructor is protected? Thanks, - Alex
_______________________________________________ mitk-users mailing list mitk-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mitk-users