template struct cv::Ptr

Overview

Template class for smart pointers with shared ownership. More…

#include <cvstd.hpp>

template <typename T>
struct Ptr
{
    // typedefs

    typedef T element_type;

    // construction

    Ptr();

    template <typename Y>
    Ptr(Y* p);

    template <
        typename Y,
        typename D
        >
    Ptr(
        Y* p,
        D d
        );

    Ptr(const Ptr& o);

    template <typename Y>
    Ptr(const Ptr<Y>& o);

    template <typename Y>
    Ptr(
        const Ptr<Y>& o,
        T* p
        );

    // methods

    template <typename Y>
    Ptr<Y>
    constCast() const;

    template <typename Y>
    Ptr<Y>
    dynamicCast() const;

    bool
    empty() const;

    T*
    get() const;

    operator T*() const;

    detail::RefOrVoid<T>::type
    operator*() const;

    T*
    operator->() const;

    Ptr&
    operator=(const Ptr& o);

    template <typename Y>
    Ptr&
    operator=(const Ptr<Y>& o);

    void
    release();

    template <typename Y>
    void
    reset(Y* p);

    template <
        typename Y,
        typename D
        >
    void
    reset(
        Y* p,
        D d
        );

    template <typename Y>
    Ptr<Y>
    staticCast() const;

    void
    swap(Ptr& o);
};

Detailed Documentation

Template class for smart pointers with shared ownership.

A Ptr <T> pretends to be a pointer to an object of type T. Unlike an ordinary pointer, however, the object will be automatically cleaned up once all Ptr instances pointing to it are destroyed.

Ptr is similar to boost::shared_ptr that is part of the Boost library (http://www.boost.org/doc/libs/release/libs/smart_ptr/shared_ptr.htm) and std::shared_ptr from the C++11 standard.

This class provides the following advantages:

  • Default constructor, copy constructor, and assignment operator for an arbitrary C++ class or C structure. For some objects, like files, windows, mutexes, sockets, and others, a copy constructor or an assignment operator are difficult to define. For some other objects, like complex classifiers in OpenCV, copy constructors are absent and not easy to implement. Finally, some of complex OpenCV and your own data structures may be written in C. However, copy constructors and default constructors can simplify programming a lot. Besides, they are often required (for example, by STL containers). By using a Ptr to such an object instead of the object itself, you automatically get all of the necessary constructors and the assignment operator.
  • O(1) complexity of the above-mentioned operations. While some structures, like std::vector, provide a copy constructor and an assignment operator, the operations may take a considerable amount of time if the data structures are large. But if the structures are put into a Ptr, the overhead is small and independent of the data size.
  • Automatic and customizable cleanup, even for C structures. See the example below with FILE*.
  • Heterogeneous collections of objects. The standard STL and most other C++ and OpenCV containers can store only objects of the same type and the same size. The classical solution to store objects of different types in the same container is to store pointers to the base class (Base*) instead but then you lose the automatic memory management. Again, by using Ptr <Base> instead of raw pointers, you can solve the problem.

A Ptr is said to own a pointer - that is, for each Ptr there is a pointer that will be deleted once all Ptr instances that own it are destroyed. The owned pointer may be null, in which case nothing is deleted. Each Ptr also stores a pointer. The stored pointer is the pointer the Ptr pretends to be; that is, the one you get when you use Ptr::get or the conversion to T*. It’s usually the same as the owned pointer, but if you use casts or the general shared-ownership constructor, the two may diverge: the Ptr will still own the original pointer, but will itself point to something else.

The owned pointer is treated as a black box. The only thing Ptr needs to know about it is how to delete it. This knowledge is encapsulated in the deleter - an auxiliary object that is associated with the owned pointer and shared between all Ptr instances that own it. The default deleter is an instance of DefaultDeleter, which uses the standard C++ delete operator; as such it will work with any pointer allocated with the standard new operator.

However, if the pointer must be deleted in a different way, you must specify a custom deleter upon Ptr construction. A deleter is simply a callable object that accepts the pointer as its sole argument. For example, if you want to wrap FILE, you may do so as follows:

Ptr<FILE> f(fopen("myfile.txt", "w"), fclose);
if(!f) throw ...;
fprintf(f, ....);
...
// the file will be closed automatically by f's destructor.

Alternatively, if you want all pointers of a particular type to be deleted the same way, you can specialize DefaultDeleter<T>::operator() for that type, like this:

namespace cv {
template<> void DefaultDeleter<FILE>::operator ()(FILE * obj) const
{
    fclose(obj);
}
}

For convenience, the following types from the OpenCV C API already have such a specialization that calls the appropriate release function:

  • CvCapture

  • CvFileStorage

  • CvHaarClassifierCascade

  • CvMat

  • CvMatND

  • CvMemStorage

  • CvSparseMat

  • CvVideoWriter

  • IplImage The shared ownership mechanism is implemented with reference counting. As such, cyclic ownership (e.g. when object a contains a Ptr to object b, which contains a Ptr to object a) will lead to all involved objects never being cleaned up. Avoid such situations.

    It is safe to concurrently read (but not write) a Ptr instance from multiple threads and therefore it is normally safe to use it in multi-threaded applications. The same is true for Mat and other C++ OpenCV classes that use internal reference counts.

Typedefs

typedef T element_type

Generic programming support.

Construction

Ptr()

The default constructor creates a null Ptr - one that owns and stores a null pointer.

template <typename Y>
Ptr(Y* p)

If p is null, these are equivalent to the default constructor. Otherwise, these constructors assume ownership of p - that is, the created Ptr owns and stores p and assumes it is the sole owner of it. Don’t use them if p is already owned by another Ptr, or else p will get deleted twice. With the first constructor, DefaultDeleter<Y>() becomes the associated deleter (so p will eventually be deleted with the standard delete operator). Y must be a complete type at the point of invocation. With the second constructor, d becomes the associated deleter. Y* must be convertible to T*. It is often easier to use makePtr instead.

Parameters:

p Pointer to own.
template <
    typename Y,
    typename D
    >
Ptr(
    Y* p,
    D d
    )

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Parameters:

d Deleter to use for the owned pointer.
p Pointer to own.
Ptr(const Ptr& o)

These constructors create a Ptr that shares ownership with another Ptr - that is, own the same pointer as o. With the first two, the same pointer is stored, as well; for the second, Y* must be convertible to T*. With the third, p is stored, and Y may be any type. This constructor allows to have completely unrelated owned and stored pointers, and should be used with care to avoid confusion. A relatively benign use is to create a non-owning Ptr, like this:

ptr = Ptr<T>(Ptr<T>(), dont_delete_me); // owns nothing; will not delete the pointer.

Parameters:

o Ptr to share ownership with.
template <typename Y>
Ptr(const Ptr<Y>& o)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Parameters:

o Ptr to share ownership with.
template <typename Y>
Ptr(
    const Ptr<Y>& o,
    T* p
    )

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Parameters:

o Ptr to share ownership with.
p Pointer to store.

Methods

template <typename Y>
Ptr<Y>
constCast() const

Ditto for const_cast.

template <typename Y>
Ptr<Y>
dynamicCast() const

Ditto for dynamic_cast.

bool
empty() const

ptr.empty() is equivalent to !ptr.get().

T*
get() const

Returns the stored pointer.

operator T*() const

Equivalent to get().

detail::RefOrVoid<T>::type
operator*() const

Ordinary pointer emulation.

T*
operator->() const

Ordinary pointer emulation.

Ptr&
operator=(const Ptr& o)

Assignment replaces the current Ptr instance with one that owns and stores same pointers as o and then destroys the old instance.

Parameters:

o Ptr to share ownership with.
template <typename Y>
Ptr&
operator=(const Ptr<Y>& o)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

void
release()

If no other Ptr instance owns the owned pointer, deletes it with the associated deleter. Then sets both the owned and the stored pointers to NULL.

template <typename Y>
void
reset(Y* p)

ptr.reset(...) is equivalent to ptr = Ptr<T>(...).

Parameters:

p Pointer to own.
template <
    typename Y,
    typename D
    >
void
reset(
    Y* p,
    D d
    )

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Parameters:

d Deleter to use for the owned pointer.
p Pointer to own.
template <typename Y>
Ptr<Y>
staticCast() const

Returns a Ptr that owns the same pointer as this, and stores the same pointer as this, except converted via static_cast to Y*.

void
swap(Ptr& o)

Swaps the owned and stored pointers (and deleters, if any) of this and o.

Parameters:

o Ptr to swap with.