[vtk-developers] Smart pointer declaration macro?

Brad King brad.king at kitware.com
Thu Jan 28 11:06:57 EST 2010


Will Schroeder wrote:
> Jeff can you summarize the proposed solutions (assuming we think we've
> covered the bases) and let's take a vote on this. I want to keep my
> inbox clear :-(

IMO a vote is the absolutely last resort if no satisfactory solution
can be found.  There are still technical alternatives (see below).
The impatient may skip to the bottom (after ------).

David Doria wrote:
> Use the survey!
>
> Then there will be no need for someone to be responsible for tallying
> the votes - it will just be automatically done.
>
> http://www.surveymonkey.com/s/8JRNJZV

Sure, but it leaves no place for discussion.  There is no indication
of what messages and discussion influenced someone's choice.

Jeff Baumes wrote:
> 1. Keep things the way they are:
> vtkSmartPointer<vtkClass> c = vtkSmartPointer<vtkClass>::New();

This is the smart pointer version of the traditional form used
in VTK since 1994:

  vtkClass* c = vtkClass::New();

The old form still had repetition; vtkSmartPointer just makes it
longer.  However, the old form could still get long:

  vtkSomeLongClassNameForAnAlgorithm* c =
    vtkSomeLongClassNameForAnAlgorithm::New();

> 2. Add new constructor to vtkSmartPointer that takes a bool and if
> true creates an instance of the object. Code would look like:
> vtkSmartPointer<vtkClass> c(true);

This can be tweaked with an enumeration value with a meaningful name:

  vtkSmartPointer<vtkClass> c(vtkSPNew);

However, the job of a smart pointer is to hold references, not
to allocate objects.

> 3. Create typedefs for vtkSmartPointer<vtkClass>:
> vtkClassSP c = vtkClassSP::New();

This is just a workaround for the length and does nothing to address
the underlying problem.

> 4. Make a new vtkLocalPointer type that is the same as vtkSmartPointer
> but always creates an instance of the object.
> vtkLocalPointer<vtkClass> c;

This is just another form of #2.  vtkLocalPointer would be a subclass
of vtkSmartPointer whose constructor allocates an instance and passes
it to it's superclass constructor.
--------------------------------------------------------------------------

The job of a smart pointer is to hold references, not to allocate objects.
Options (2) and (4) violate this well-established role.  A simple example
shows this:

  vtkSmartPointer<vtkObject> c = vtkSmartPointer<vtkPolyData>::New();

The LHS will gladly accept the derived object but could not have allocated
one.  We must preserve the LHS syntax:

 vtkSmartPointer<vtkObject> c

to clearly distinguish the role of a smart pointer.  This is true of other
common smart pointer implementations such as the boost::shared_ptr:

  boost::shared_ptr<MyBaseType> p(new MyDerivedType);

We cannot avoid the duplication of the vtkClass name while still keeping
the "base=new base" case consistent with the "base = new derived" case.
The VTK-ish equivalent of the shared_ptr initialization is

  vtkSmartPointer<vtkObject> c = vtkPolyData::New();

but it leaks the reference owned by the raw pointer returned by New().

We cannot just change vtkClass::New() to return a vtkSmartPointer<vtkClass>
so we need an alternative way to create objects.  Our current alternative
is vtkSmartPointer<vtkClass>::New(), but the whole point of this discussion
is that it's too long.  We can shorten it with a new function template:

  template <class T>
  vtkSmartPointer<T> vtkNew() { return vtkSmartPointer<T>::New(); }

leading to:

  vtkSmartPointer<vtkObject> c = vtkNew<vtkPolyData>();

Beyond that, the verbosity is an artifact of using C++ as a language
and the non-abbreviated name "vtkSmartPointer".  We could change it
to something shorter, like "vtkRef", but that will just leave two
names for the same thing.

-Brad



More information about the vtk-developers mailing list