# vtkNew and vtkSmartPointer

**URL:** https://discourse.vtk.org/t/vtknew-and-vtksmartpointer/469
**Category:** Development
**Created:** [March 13, 2019, 1:35am UTC](https://discourse.vtk.org/t/vtknew-and-vtksmartpointer/469 "2019-03-13T01:35:54Z")
**Posts on this page:** 1
**Showing post:** 9

<div class="post-metadata">

### Author: ![allison.vacanti](https://discourse.vtk.org/user_avatar/discourse.vtk.org/allison.vacanti/32/679_2.png) [@allison.vacanti](https://discourse.vtk.org/u/allison.vacanti)
#### Post date: [March 16, 2019, 3:23pm UTC](https://discourse.vtk.org/t/vtknew-and-vtksmartpointer/469/9 "2019-03-16T15:23:02Z")

</div>

> [@mwestphal](#):
>
> you can’t return a vtkNew.

This used to be true, until a few weeks ago:

[https://gitlab.kitware.com/vtk/vtk/merge\_requests/5223](https://gitlab.kitware.com/vtk/vtk/merge_requests/5223)

Now `vtkNew` has move semantics, and can be returned:

```auto
vtkNew<vtkDataSet> ObjectFactory()
{
  vtkNew<vtkPolyData> pd;
  Configure(pd);
  return pd;
}

void Work()
{
  vtkSmartPointer<vtkObject> object; // empty

  { // Create new scope
    // Implicitly moves the returned objects into dObj1 and dObj2;
    vtkNew<vtkDataObject> dObj1 = ObjectFactory();
    vtkNew<vtkDataObject> dObj2 = ObjectFactory();

    // The dangling returned pointer is immediately destroyed properly:
    ObjectFactory();

    // dObj1 (vtkNew) is moved into object (vtkSmartPointer) 
    // and set to nullptr. dObj2 remains valid.
    object = std::move(someTrueCondition ? dObj1 : dObj2); 
  } // dObj2 is destroyed
  
  Foo(object); // do some work with dObj1

} // dObj1's original data is freed as object is destroyed

```

The new standard guarantees the we’ll elide the copy via NRVO in ObjectFactory(), and since the type-converting move constructors are present the type cast works as expected. The returned object will have a reference count of one and will clean itself up if dangled, or else must be moved into a different `vtkNew` or `vtkSmartPointer`, possibly converting type up the inheritance chain.

> [@lorensen](#):
>
> vtkNew is not friendly with some STL containers

The move semantics also mean that `vtkNew` pointers can now be stored in containers like `std::vector`, since the containers are now guaranteed by the standard to move elements instead of copy them when `noexcept` move constructors are available. They’ll work as desired during vector reallocation and free themselves when the vector is destroyed. There are some restrictions – the `std::vector` of `vtkNew` becomes move-only as well, but under the ownership semantics implied by `vtkNew`, this is still useful.

All of the smart pointers got a little C++11 polish with that branch and learned some new tricks. The major difference remaining between New and Smart is `vtkNew` has both move-assignment and copy-assignment disabled, meaning that once a pointer goes into a `vtkNew,` it cannot change. It will go to `nullptr` if moved out, but it cannot be moved into or otherwise replaced once constructed.

IMO they’re both still useful to have because of convention – `vtkNew` means “I own this pointer, which must remain the same for my lifetime”, `vtkSmartPointer` means “I use this pointer, which came from somewhere else and might change,” which is useful to know at a glance when maintaining code.

---

_[View the full topic](https://discourse.vtk.org/t/vtknew-and-vtksmartpointer/469)._
