0

I have some generic code for deleting pointers within a vector or a value of a Map.

Is there a better way of doing this (without using shared_ptrs or any o fthe tr1 extensions )?

Also is the code correct?

Here is my code:

I have a namespace

#ifndef CONTAINERDELETE_H #define CONTAINERDELETE_H #include <functional> #include <map> #include <vector> #include <algorithm> namspace ContainerDelete{ template<class A, class B> struct DeleteMap { bool operator()( pair<A,B> &x) const { delete x.second; return true; } }; template<class T> struct DeleteVector { bool operator()(T &x) const { delete x; return true; } }; } #endif 

I would then use this namespace in some bit of code to delete a map or vector.

Test Map deletion.

#include "ContainerDelete.h" using namespace std; // Test function. void TestMapDeletion() { // Add 10 string to map. map<int,B*> testMap; for( int Idx = 0; Idx < 10; ++Idx ) { testMap[Idx] = new B(); } // Now delete the map in a single line. for_each( testMap.begin(), testMap.end(), ContainerDelete::DeleteMap<int,B*>()); } 

Test Vector Deletion

// Test Function. void TestVectorDeletion() { // Add 10 string to vector. vector<B*> testVector; for( int Index = 0; Index < 10; ++Index ) { testVector.push_back( new B()); } // Now delete the vector in a single line. for_each( testVector.begin(), testVector.end(), ContainerDelete::DeleteVector<B*>()); } 

Thanks,

Mike

6
  • 2
    shared_ptr is now standard (gcc 4.5 and VS2010 both support it), but if you don't want to use it until fully conforming compilers, you can use boost::shared_ptr which is almost the same. I would advise against implementing your own solution because there are lots of tricky corner-cases (unless you are doing it for educational purposes which is fine). Commented Nov 22, 2011 at 17:31
  • In C++11 the first attempt would always be to make the element type std::unique_ptr<T> and only look for alternatives if that doesn't fit your needs. Containers of raw pointers are always a bad idea because you don't know who owns the pointed-to objects. You might even have a mix of pointers to dynamic, static and automatic variables. How would the container be able to restrict the amount of damage you can do? Commented Nov 22, 2011 at 17:35
  • @KerrekSB The main problem that I have in my current code setup is the order in which I delete the pointers (as I pass by pointers by reference). I need to make sure I work from the last reference backwards so not to get dangling pointer? Would this be a good place to use shared_ptr Commented Nov 22, 2011 at 18:09
  • @MWright: I don't follow. How does the order matter? Do the pointed-to objects know of each other? That sounds like a maintenance nightmare... Commented Nov 22, 2011 at 18:33
  • @KerrekSB Sorry for not being clear. I use alot of pointers to pointers and pointers to vectors of pointers in my code. These objects also get passed to other classes by reference so I need to keep track of them. These pointer are regular pointers and not smart pointers. Would it be in my best interest to bite the built and recode using shared_ptr so my memory is handled appropriately? Commented Nov 22, 2011 at 19:40

2 Answers 2

2

Better would be if reduce the genericity as:

struct DeleteVector { template<class T> //use the template here! void operator()(T &x) const { delete x; } }; 

if you do so, then you could simply write this:

for_each(testVector.begin(), testVector.end(), ContainerDelete::DeleteVector()); 

No need to pass type argument when you use DeleteVector, for it is not a class template anymore!

Similarly, you can implement DeleteMap functor.

You should also rename DeleteVector to DeleteT, and DeleteMap to DeletePairSecond, as both of these can be used more generically. For example, DeleteT can be used even with std::list, or even with arrays.

Sign up to request clarification or add additional context in comments.

4 Comments

this does look cleaner. Would I not need to have a return though in the overloaded operator () ?
But you declared it as returning a bool, should be void surely?
@BleepBloop: Oops. Yes. It was just a typo.
I thought I was going crazy! Thanks
0

The code is ok. I can't imagine any other ways to delete the pointers. All you can do is to reduce explicit type specification like in upper question. I know one more uglier way to do it: functions deduce types of their template parameters. So you can write template function with the first argument - vector, second - ptr and then use std::bind of vector parameter to make this function accepting one parameter - ptr. But functor is better and more flexible.

1 Comment

shared pointers can be very slow. If you don't copy the pointers intensively it's better to use them.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.