Vector of Obj can be very poor for performance, since a vector could have to move object on resize and has to copy them all. Pointers to objects are better.
I've used Pointainers which will do what you need. Here is the original code.
/*
* pointainer - auto-cleaning container of pointers
*
* Example usage:
* {
* pointainer< std::vector<int*> > v;
* // v can be manipulated like any std::vector<int*>.
*
* v.push_back(new int(42));
* v.push_back(new int(17));
* // v now owns the allocated int-s
*
* v.erase(v.begin());
* // frees the memory allocated for the int 42, and then removes the
* // first element of v.
* }
* // v's destructor is called, and it frees the memory allocated for
* // the int 17.
*
* Notes:
* 1. Assumes all elements are unique (you don't have two elements
* pointing to the same object, otherwise you might delete it twice).
* 2. Not usable with pair associative containers (map and multimap).
* 3. For ANSI-challenged compilers, you may want to #define
* NO_MEMBER_TEMPLATES.
*
* Written 10-Jan-1999 by Yonat Sharon <yonat@@ootips.org>
* Last updated 07-Feb-1999
*
* Modified June 9, 2003 by Steve Fossen
* -- to fix g++ compiling problem with base class typenames
*/
#ifndef POINTAINER_H
#define POINTAINER_H
#ifdef NO_MEMBER_TEMPLATES
#include <functional> // for binder2nd
#endif
template <typename Cnt>
class pointainer : public Cnt
{
public:
// sf - change to fix g++ compiletime errors
#ifdef USE_USING_NOT_TYPEDEF
// I get compile errors with this
using typename Cnt::size_type;
using typename Cnt::difference_type;
using typename Cnt::reference;
using typename Cnt::const_reference;
using typename Cnt::value_type;
using typename Cnt::iterator;
using typename Cnt::const_iterator;
using typename Cnt::reverse_iterator;
using typename Cnt::const_reverse_iterator;
#else
// this way works
typedef typename Cnt::size_type size_type;
typedef typename Cnt::difference_type difference_type;
typedef typename Cnt::reference reference;
typedef typename Cnt::const_reference const_reference;
typedef typename Cnt::value_type value_type;
typedef typename Cnt::iterator iterator;
typedef typename Cnt::const_iterator const_iterator;
typedef typename Cnt::reverse_iterator reverse_iterator;
typedef typename Cnt::const_reverse_iterator const_reverse_iterator;
#endif
typedef pointainer< Cnt > its_type;
pointainer() {}
pointainer( const Cnt &c ) : Cnt( c ) {}
its_type &operator=( const Cnt &c ) { Cnt::operator=( c ); return *this; }
~pointainer() { clean_all(); }
void clear() { clean_all(); Cnt::clear(); }
iterator erase( iterator i ) { clean( i ); return Cnt::erase( i ); }
iterator erase( iterator f, iterator l ) { clean( f, l ); return Cnt::erase( f, l ); }
// for associative containers: erase() a value
size_type erase( const value_type& v )
{
iterator i = find( v );
size_type found( i != end() ); // can't have more than 1
if( found )
erase( i );
return found;
}
// for sequence containers: pop_front(), pop_back(), resize() and assign()
void pop_front() { clean( begin() ); Cnt::pop_front(); }
void pop_back() { iterator i( end() ); clean( --i ); Cnt::pop_back(); }
void resize( size_type s, value_type c = value_type() )
{
if( s < size() )
clean( begin() + s, end() );
Cnt::resize( s, c );
}
#ifndef NO_MEMBER_TEMPLATES
template <class InIter> void assign(InIter f, InIter l)
#else
void assign( iterator f, iterator l )
#endif
{
clean_all();
Cnt::assign( f, l );
}
#ifndef NO_MEMBER_TEMPLATES
template <class Size, class T> void assign( Size n, const T& t = T() )
#else
void assign( size_t n, const value_type& t = value_type() )
#endif
{
clean_all();
Cnt::assign( n, t );
}
// for std::list: remove() and remove_if()
void remove( const value_type& v )
{
clean( std::find( begin(), end(), v ));
Cnt::remove( v );
}
#ifndef NO_MEMBER_TEMPLATES
template <class Pred>
#else
typedef std::binder2nd< std::not_equal_to< value_type > > Pred;
#endif
void remove_if(Pred pr)
{
for( iterator i = begin(); i != end(); ++i )
if( pr( *i ))
clean( i );
Cnt::remove_if( pr );
}
private:
void clean( iterator i ) { delete *i; *i = 0; } // sf add *i = NULL so double deletes don't fail
void clean( iterator f, iterator l ) { while( f != l ) clean( f++ ); }
void clean_all() { clean( begin(), end() ); }
// we can't have two pointainers own the same objects:
pointainer( const its_type& ) {}
its_type& operator=( const its_type& ) { return NULL;} // sf - return null to remove no return value warning..
};
#endif // POINTAINER_H