Difference between revisions of "VTK/Tutorials/SmartPointers"
Daviddoria (talk | contribs) |
Daviddoria (talk | contribs) (→Usage) |
||
Line 3: | Line 3: | ||
==Usage== | ==Usage== | ||
===Creating an Object with a Smart Pointer=== | |||
One way to create a VTK object is | One way to create a VTK object is | ||
<source lang="cpp"> | <source lang="cpp"> | ||
Line 24: | Line 25: | ||
</source> | </source> | ||
=== Getting an Object with a Smart Pointer === | |||
When not allocating memory for an object, you can still use smart pointers. Take this simple example: | When not allocating memory for an object, you can still use smart pointers. Take this simple example: | ||
<source lang="cpp"> | <source lang="cpp"> | ||
Line 36: | Line 38: | ||
In the first case, when the reader object goes out of scope, the data is deleted. In the second case, by using a smart pointer we have incremented the data's reference count by 1, so the data will not be deleted until the reader AND the polydata object go out of scope. | In the first case, when the reader object goes out of scope, the data is deleted. In the second case, by using a smart pointer we have incremented the data's reference count by 1, so the data will not be deleted until the reader AND the polydata object go out of scope. | ||
===Returning a | === Returning a Smart Pointer === | ||
If you define a function like this: | If you define a function like this: | ||
<source lang="cpp"> | <source lang="cpp"> | ||
Line 63: | Line 65: | ||
because (!!! is this different? if so, why?) | because (!!! is this different? if so, why?) | ||
=== Putting an Existing Object into a Smart Pointer === | |||
==Pitfalls== | ==Pitfalls== |
Revision as of 13:33, 5 November 2009
Idea
The idea behind smart pointers is reference counting. If the object goes out of scope and it is not being used anywhere else, it will be deleted automatically. Pretty 'smart', eh?
Usage
Creating an Object with a Smart Pointer
One way to create a VTK object is
vtkObject* MyObject = vtkObject::New();
This method, however, can (and likely will) lead to memory management issues at some point or another. You must manually delete the object
MyObject->Delete();
or you will have a memory leak. VTK's solution to this ever-annoying problem is the smart pointer. To use it, you must
#include "vtkSmartPointer.h"
Then you can create an object as follows:
vtkSmartPointer<vtkObject> MyObject = vtkSmartPointer<vtkObject>::New();
Getting an Object with a Smart Pointer
When not allocating memory for an object, you can still use smart pointers. Take this simple example:
vtkSmartPointer<vtkXMLPolyDataReader> Reader = vtkSmartPointer<vtkXMLPolyDataReader>::New();
vtkPolyData* pd = Reader->GetOutput();
vs
vtkSmartPointer<vtkPolyData> pd = Reader->GetOutput();
In the first case, when the reader object goes out of scope, the data is deleted. In the second case, by using a smart pointer we have incremented the data's reference count by 1, so the data will not be deleted until the reader AND the polydata object go out of scope.
Returning a Smart Pointer
If you define a function like this:
vtkSmartPointer<vtkPolyData> MyFunction()
{
vtkSmartPointer<vtkPolyData> MyObject = vtkSmartPointer<vtkPolyData>::New();
return MyObject;
}
And call the function using:
vtkSmartPointer<vtkPolyData> MyPolydata = MyFunction();
This is different from:
vtkPolyData* MyFunction()
{
vtkSmartPointer<vtkPolyData> MyObject = vtkSmartPointer<vtkPolyData>::New();
return MyObject;
}
vtkPolyData* MyPolydata = MyFunction();
because (!!! is this different? if so, why?)
Putting an Existing Object into a Smart Pointer
Pitfalls
- If you create an object and then change where it is pointing, the reference count will be incorrect. e.g.
vtkSmartPointer<vtkPolyData> Polydata = vtkSmartPointer<vtkPolyData>::New();
Polydata = Reader->GetOutput();
In this case, memory is allocated for Polydata, but then we change Polydata to point to the output of Reader rather than the memory we just allocated. Instead, we should have done simply:
vtkPolyData* Polydata = Reader->GetOutput();
It was not necessary to use a smart pointer because we did not actually create any new objects.
Example
Here is an example of equivalent operations with and without smart pointers:
SmartPointers.cpp
#include <vtkFloatArray.h>
#include <vtkSmartPointer.h>
#include <iostream>
void WithSmartPointers();
void WithoutSmartPointers();
int main(int argc, char *argv[])
{
WithSmartPointers();
WithoutSmartPointers();
return 0;
}
void WithSmartPointers()
{
vtkSmartPointer<vtkFloatArray> Distances = vtkSmartPointer<vtkFloatArray>::New();
}
void WithoutSmartPointers()
{
vtkFloatArray* Distances = vtkFloatArray::New();
Distances->Delete();
}
CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
PROJECT(SmartPointers)
FIND_PACKAGE(VTK REQUIRED)
INCLUDE(${VTK_USE_FILE})
ADD_EXECUTABLE(SmartPointers SmartPointers.cpp)
TARGET_LINK_LIBRARIES(SmartPointers vtkHybrid)