Commit 1a608359 authored by Marcus D. Hanwell's avatar Marcus D. Hanwell
Browse files

ENH: Added vtkNew - scoped new VTK objects.

This commit adds a new templated pointer type - vtkNew. It has the
advantage of one step initialization of VTK objects, that will be
deleted once the vtkNew object goes out of scope. A new test was also
added demonstrating and testing its functionality.

Change-Id: I35ec37d39dafc8e1139821fbe5b6204178ae9776
parent faa39cbb
......@@ -523,6 +523,7 @@ IF(NOT VTK_INSTALL_NO_DEVELOPMENT)
vtkDenseArray.h
vtkIOStream.h
vtkIOStreamFwd.h
vtkNew.h
vtkSetGet.h
vtkSmartPointer.h
vtkSystemIncludes.h
......
......@@ -18,6 +18,7 @@ CREATE_TEST_SOURCELIST(Tests ${KIT}CxxTests.cxx
TestMath.cxx
TestMatrix3x3.cxx
TestMinimalStandardRandomSequence.cxx
TestNew.cxx
TestObservers.cxx
TestPolynomialSolversUnivariate.cxx
TestSmartPointer.cxx
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestSmartPointer.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// .NAME Test of vtkNew.
// .SECTION Description
// Tests instantiations of the vtkNew class template.
#include "vtkDebugLeaks.h"
#include "vtkFloatArray.h"
#include "vtkIntArray.h"
#include "vtkNew.h"
#include "vtkSmartPointer.h"
#include "vtkWeakPointer.h"
int TestNew(int,char *[])
{
bool error = false;
// This one should be cleaned up when the main function ends.
vtkNew<vtkIntArray> a;
if (a->GetReferenceCount() != 1)
{
error = true;
cerr << "Error, reference count should be 1, was " << a->GetReferenceCount()
<< endl;
}
cout << "vtkNew streaming " << a << endl;
vtkWeakPointer<vtkFloatArray> wf;
// Test scoping, and deletion.
if (wf == 0)
{
vtkNew<vtkFloatArray> f;
wf = f.GetPointer();
}
if (wf != 0)
{
error = true;
cerr << "Error, vtkNew failed to delete the object it contained."
<< endl;
}
// Now test interaction with the smart pointer.
vtkSmartPointer<vtkIntArray> si;
if (si == 0)
{
vtkNew<vtkIntArray> i;
si = i.GetPointer();
}
if (si->GetReferenceCount() != 1)
{
error = true;
cerr << "Error, vtkNew failed to delete the object it contained, "
<< "or the smart pointer failed to increment it. Reference count: "
<< si->GetReferenceCount() << endl;
}
return error ? 1 : 0;
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkNew.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// .NAME vtkNew - Hold a reference to a vtkObjectBase instance.
// .SECTION Description
// vtkNew is a class template that on construction allocates and
// initializes an instance of its template argument using T::New().
// It assumes ownership of one reference during its lifetime, and calls
// T->Delete() on destruction.
//
// Automatic casting is intentionally unavailable, calling GetPointer() will
// return a raw pointer. Users of this method should ensure that they do not
// return this pointer if the vtkNew will go out of scope without
// incrementing its reference count using vtkSmartPointer or similar.
//
// \code
// vtkNew<vtkClass> a;
// a->SomeMethod();
//
// vtkSmartPointer<vtkClass> b = a.GetPointer();
// b->SomeOtherMethod();
#ifndef __vtkNew_h
#define __vtkNew_h
#include "vtkIOStream.h"
class vtkObjectBase;
template <class T>
class vtkNew
{
// Description:
// Compile time checking that the class is derived from vtkObjectBase.
void CheckObjectBase(vtkObjectBase*) {}
public:
// Description:
// Create a new T on construction.
vtkNew() : Object(T::New())
{
this->CheckObjectBase(this->Object);
}
// Description:
// Deletes reference to instance of T on destruction.
~vtkNew()
{
T* obj = this->Object;
if (obj)
{
this->Object = 0;
obj->Delete();
}
}
// Description:
// Enable pointer-like dereference syntax. Returns a pointer to the contained
// object.
T* operator->() const
{
return this->Object;
}
// Description:
// Get a raw pointer to the contained object. When using this function be
// careful that the reference count does not drop to 0 when using the pointer
// returned. This will happen when the vtkNew object goes out of
// scope for example.
T* GetPointer() const
{
return this->Object;
}
private:
vtkNew(vtkNew<T> const&); // Not implemented.
void operator=(vtkNew<T> const&); // Not implemented.
T* Object;
};
// Description:
// Streaming operator to print scoped pointer like regular pointers.
template <class T>
inline ostream& operator << (ostream& os, const vtkNew<T>& p)
{
return os << p.GetPointer();
}
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment