473,322 Members | 1,314 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,322 software developers and data experts.

How can an object ask to be deleted?

emibt08
25
I have a class, say Container which contains objects of another class, for example MyObject. MyObject does some processing, and in some future time it is no longer needed. Hence, it should somehow tell to the Container about it. I currently do something like this:

Expand|Select|Wrap|Line Numbers
  1. class MyObject
  2. {
  3. public:
  4.     typedef void(*PFN)(void*,MyObject*);
  5.     MyObject(void* param, PFN p) : m_param(param), m_pfn(p) {}
  6.     // some other functions
  7.  
  8. private:
  9.     void Done() { m_pfn(m_param, this); }
  10.  
  11.     void* m_param;
  12.     PFN    m_pfn;
  13. };
  14.  
  15. class Container
  16. {
  17. public:
  18.     Container()
  19.     {
  20.         // ...
  21.         // just an example
  22.         for (int i = 0; i != 100; ++i)
  23.         {
  24.             MyObject* pobj = new MyObject(this, MyObjectCallback);
  25.             m_Vector.push_back(pobj);
  26.         }
  27.     }
  28.  
  29.     // other functions...
  30.  
  31. static DWORD WINAPI MyObjectCallback(void* p, MyObject* pobj)
  32. {
  33.     Container *pThis = (Container*)p;
  34.  
  35.     pThis->lockVector();
  36.     vector<MyObject*>::iterator it = pThis->m_Vector.begin();
  37.     while (it != pThis->m_Vector.end())
  38.     {
  39.         if (*it == pobj)
  40.         {
  41.             delete *it;
  42.             pThis->m_Vector.erase(it);
  43.             break;
  44.         }
  45.         else
  46.             ++it;
  47.     }
  48.     pThis->unlockVector();    
  49. }    
  50.  
  51. private:
  52.     vector<MyObject*> m_Vector;
  53. };
  54.  

I could create a thread in the Container class and poll the objects, which can provide something like: bool DoneProcessing() and then can be deleted, but i believe it may be a worse solution.
So, I wonder if it's safe to do the things the way i do: deleting the object in the callback function that it called, or maybe there is a better solution that i haven't thought of...

Thanks in advance
Feb 6 '10 #1
4 2304
weaknessforcats
9,208 Expert Mod 8TB
Get a book on Design Patterns and look up the Observer pattern.

The Observer pattern uses the "notify" concept for an object to notify any "observers" that it's contents have changed.

This sounds like your situation.
Feb 6 '10 #2
emibt08
25
Thanks for the reply... however, after checking the observer pattern a little better, I doubt it applies here. I could use it to notify the main thread that the object is finished with the processing, but with that pattern i may have more than 1 observer. In my case, I have only one, so it's not a problem, but if i had more and the 1st deleted the object, then i suppose the object can't notify the others (or i am not even sure what will happen).

However, the problem is simply.. how can an object tell to another onject to delete it?
Like, in my case MyObject calls the callback that was provided to it and calls it. But in that call the callee wants to delete the MyObject. I have tested this and succeeds, whether it is a coincidence or not.
In my understanding, when a function is called it puts it's address on the call stack and everything, but isn't that address invalidated when i delete the object?

It's like this:

Expand|Select|Wrap|Line Numbers
  1. Container *pCont = new Container();
  2. MyObject *pObj = new MyObject();
  3. pObj->setCallback(pCont->CallBack);
  4. pCont->add(pObj);
  5.  
// after some time, in some function of MyObject, pObj does:
Expand|Select|Wrap|Line Numbers
  1. {
  2.     pFunc(this);
  3.  
  4.     // I suppose the control will never come to this point,
  5.     // because of what happens in the callback....
  6.     // however, in the debuger it does...
  7. }
  8.  
// which calls the callback:
Expand|Select|Wrap|Line Numbers
  1. Container::CallBack(MyObject *sender)
  2. {
  3.     delete sender;
  4. }
  5.  
I suppose it's like calling "delete this" from some function in MyObject (which i don't know if it is completely valid to do, although i know i can do it and works)
Feb 7 '10 #3
weaknessforcats
9,208 Expert Mod 8TB
An object can have multiple observers.

Usually, the observers register themselves with a Mediator (another pattern) and the Mediator notifies all observers when the object call its Notify() method.

All you have to do is pass a message in your Notify() requesting the desired action, like delete this object.
Feb 8 '10 #4
As simple as it sounds, I don’t think you can directly do what you want. For example, an object cannot commit suicide, i.e., it can’t delete itself. What would happen to the thread?

For much the same reason, your component cannot ask its container to delete it. The thread would be going from the component to the container where the container would delete it and then back to … what?

Asking another object to delete the caller is like kicking the ladder out from underneath the object being called to do the deleting.

About the best you can do is mark the component for deletion and let another thread clean it up. That thread could be a “maintenance” thread in the container, which deletes marked objects. Or it could be a callback thread, which is kind of what you described. The callback works, because they are often separate threads. So while your component commences the callback through a notification, it’s probably not the thread that implements the callback. This allows the container to clean up the marked component without having the rug pulled out from under its feet.

If this still doesn’t sound like a clean implementation, consider how garbage collection works. Objects are marked for clean up when they have no pointers to them, and then the garbage collector, on a separate thread, looks for them and releases their resources. This is basically what Java does: http://www.javaworld.com/javaworld/j.../jw-08-gc.html
May 7 '10 #5

Sign in to post your reply or Sign up for a free account.

Similar topics

3
by: Cary Linkfield | last post by:
I have created a custom class inheriting CollectionBase and implementing IBindingList. I am binding the list to a datagrid. I would like to have a property on the class that works like the...
15
by: Rick | last post by:
Hi, Does deleting an object more than one times incur undefined behavior? I think it doesn't but just making sure... thanks Rick
4
by: lauch2 | last post by:
I have a project that contains a COM object running in the in-process configuration. The project was developed by VC6.0 with SP 3. The project has been put into production for long period of time...
15
by: cedgington | last post by:
I wanted to take advantage of the large set of functionality offered by the framework, so for my latest project I'm using managed C++ with .NET v2. I'm using the gcnew operator in two different...
4
by: semkin55 | last post by:
Here is a small program, that traces construction and distruction of class A objects. If I use make_pair to insert in a map everything is OK. If I insert using , than objects with index 11, 7 and...
12
by: better_cs_now | last post by:
Hello all, I suspect that a threading issue is leading to an object being destructed in one thread context while one of its member functions is still running in another thread context. As a...
15
by: mark.norgate | last post by:
Hello I want to create a reference to an object, so that changes to the referenced object are reflected in the other object. Like this: object o = 123; object p = o; o = 456;
14
by: Mark | last post by:
Hi, I would like to check if my object has been deleted or not, but my program keeps crashing. Here's the simplified code (in infinite loop) delete tetromino; //if(tetromino==NULL)...
0
by: =?Utf-8?B?SmVhbi1GcmFuY29pcyBCcmV0b24=?= | last post by:
"siddharthkhare@hotmail.com" wrote: The context is important in this kind of design concern : I assume there's a lot of user and that application will evolve to add richer functionality. My...
0
by: Terry Reedy | last post by:
Karl Kobata wrote: Please post code that works. Use cut and paste. Have you read the manual section on the del statement? Most programs use del rather sparingly. Most temporary objects...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.