2

i got this class to get a list of all derived objects

Register.h
-----------------
class Register {
...
public:

// static object list
static list<Register*> instances;

// default constructor for register object
Register::Register();

// virtual destructor to clean up with subobject destructor first
virtual Register::~Register();

// default methods for this class
static void Register::stop();

Register.cpp
-----------------
#include "Register.h"

// list with all object instances made by this programm
list<Register*> Register::instances;

// default destructor
Register::~Register() {
  list<Register*>::iterator p = find(instances.begin(), instances.end(), this);
  if (p != instances.end()) {
    instances.erase(p);
  }
}

// erase all instances clean up the dish
void Register::stop() {
  // last log message
  Log::write("register cleanup");
  // stops the logging object
  Log::stop();
  // clean up instances
  list<Register*>::iterator iter = instances.begin();
  list<Register*>::iterator end  = instances.end();
  while (iter != end) {
    cout<< endl << (*iter) -> typeName << endl;
    //delete *iter;
  }
  Register::instances.clear();
}

and derived classes

File.h
-----------------
class File : public Register {
...
// default destructor
virtual File::~File(void);
...
}

File.cpp
-----------------
// default destructor
File::~File(void) {
  cout << "file destr";
  this -> deleteFile();
}

Log.h
-----------------
// this class implements a log handler
// (derived from register)
class Log : public File {

public:
  // singelton logging object
  static Log* log;

  // default destructor
  Log::~Log(void);

Log.cpp
-----------------
using namespace std;

// declare pointer for easy logging
Log* Log::log = NULL;

// default destructor
Log::~Log(void) {
cout << "log destr";
}

now i want to delete the whole structure with simply delete the list and the objects in it..

i tried with

 Main.cpp
-----------------
 int main (int argc, char *argv[], char *envp[]) {

   Register::stop();

   return 1;
 }

but the objects are still instanced

i´m out of ideas ^^

kindly..

Alex Tape
  • 2,291
  • 4
  • 26
  • 36

3 Answers3

3

Register::instances.clear();

This clears list of pointers, but doesn't do anything with objects. You need to remove them yourself before clearing the list, e.g. like this

for (list<Register *>::iterator it = Register::instances.begin();
     it != Register::instances.end();
     ++it) {
    delete *it;
}
Register::instances.clear();
xaizek
  • 5,098
  • 1
  • 34
  • 60
  • i apreciate.. but then vs++ throws Debug Assertion Failed! Expression: list iterator not incrementable.. :-( – Alex Tape Aug 15 '12 at 14:36
  • @AlexTape: See [list iterator remove](http://stackoverflow.com/questions/1016307/list-iterator-remove). If your destructor is responsible for removing the object from the list, this operation modifies the list and invalidates the iterator. – DCoder Aug 15 '12 at 14:48
  • @AlexTape I think @Pete is right, destructor of `Register` or one of its derived classes (`Log` probably) modifies list. Basically, there is no other explanation for the assert you get. – xaizek Aug 15 '12 at 15:43
  • your right.. i solved nothing.. and even if i call the delete *it it throws the "Expression: list iterators incompatible" again... – Alex Tape Aug 16 '12 at 09:28
  • @AlexTape show us your destructors (it's probably better to add it to question). If you want to remove items from list in their destructors, you can use `while(instances.size()) delete *instances.begin();`. – xaizek Aug 16 '12 at 10:07
  • 1
    @AlexTape Try `while(instances.size() > 0) delete *instances.begin();`, it should work for this case. But mention near loop that list items are deleted in item's destructor. – xaizek Aug 16 '12 at 11:06
  • you definetly MADE MY DAY :-) – Alex Tape Aug 16 '12 at 11:36
2

As an alternative to manually clearing the list, C++11 introduced the std::unique_ptr<> smartpointer which is compatible with STL containers.

static std::list<std::unique_ptr<Register>> instances;

will basically take care of deleting the objects.

Christian Stieber
  • 9,954
  • 24
  • 23
0

ok.. i solved it..

// clean up instances
list<Register*>::iterator iter = instances.begin();
list<Register*>::iterator end  = instances.end();

while (iter != end) {
  iter = instances.erase(iter);
}
Register::instances.clear();
Alex Tape
  • 2,291
  • 4
  • 26
  • 36
  • If you intended to delete the objects pointed to by the pointers in the list, then you are not doing that here. – juanchopanza Aug 15 '12 at 15:40
  • Actually, now `clear()` does nothing and you do its job in a `while` loop. Neither `erase()` nor other function won't release object for you. Solutions from both other answers should work. – xaizek Aug 15 '12 at 15:40
  • `for (list::iterator iter = instances.begin(); iter != instances.end(); ++iter) delete *iter; instances.clear();` – Pete Becker Aug 15 '12 at 15:47