Can An Object Delete Itself?

Would that work? No doubt a strange thing to want to do, but I have an application where it would be quite handy - once the object has done its job, it needs to be deleted, but I don’t want to hang onto a reference to it while it works. So, can you do: delete this; in a member function, then return, to free up the memory? Seems to me it should work…

Regards,
Ray L.

You mean “destructor”?

I'm not an OOP programmer, so the below might be considered a workaround,

Declare the object in a function, call the function. When you leave the function, the object is destroyed. But I guess that you have considered that and it does not suite you.

Second option: using a statemachine approach, instantiate the object in the first state, destroy the object in the final state.

I don't want to hang onto a reference to it while it works.

On one hand, to call this method you must have a "reference" (i.e., instance). That instance is still "in scope" after the method returns, unless you are doing something like this:

     Instance_t *instancePtr = fromSomePlace();
     instancePtr -> methodThatDeletesThis();
      //  instancePtr points to deleted memory now (dangling)
  } // instancePtr goes out of scope here

OTOH, there's nothing sacred about this:

void Instance_t::methodThatDeletesThis()
{
  this->doSomething();
  delete this;
}

IMPORTANT OBSERVATION: if you can delete this immediately, why not do the obvious (and RECOMMENDED) delete in the caller?

     Instance_t *instancePtr = fromSomePlace();
     instancePtr -> method();
     delete instancePtr;
      //  instancePtr points to deleted memory (dangling)
  } // instancePtr goes out of scope here

Deleting this is asking for trouble, though. What if you call it like this:

    Instance_t instance( args );
      ...
    instance.doSomeThings();
    instance.methodThatDeletesThis();

Bad.

It's just not good practice -- that's why you've never seen this.

There are many techniques for this kind of garbage collection. Your special method could add it to a list of things to be deleted, then process that list at a later time (e.g., in loop).

Even better, put it back into the pool of available instances. Then getting an instance to use is just calling a "factory" method to pull the next available instance out of the pool (i.e., return a pointer). Your pool could be constructed as an array of instances.

This also avoids all the dynamic memory issues: fragmentation and non-deterministic search for available memory. You still have to handle exhaustion, but it's a test for pool->empty(), not (new Instance_t) == nullptr.

Cheers, /dev


P.S. stackoverflow Q&A here.

It would be a real PITA to have to keep track of the objects, and would limit how many can exist at any given time. Each is a client object which handles sending a single message, waiting for the response, and can then be tossed away. The object may exist for a millisecond, or several seconds. I create the client object, which spins off a separate thread to handle the communications, and immediately returns to the caller. The object times out by itself if there is any error, so the most convenient thing is to simply treat the object creation as a "fire and forget", and let the object delete itself once the send is either completed or fails. The fact that the send/receive actually runs in another thread has no real bearing on the question, as the same functionality could be implemented in a single-threaded world.

Regards, Ray L.

Well, there's one solution that works - I simply made the client a fully static object, so no need to delete, and I can create as many as I want, with the only overhead being a little stack space. But I'd still like to know of the self-delete would work. Maybe need to write a quick test program...

Regards, Ray L.

RayLivingston: Each is a client object which handles sending a single message, waiting for the response, and can then be tossed away.

Why toss it away? Put it on a free list / recycle it.

RayLivingston: Would that work? No doubt a strange thing to want to do, but I have an application where it would be quite handy - once the object has done its job, it needs to be deleted, but I don't want to hang onto a reference to it while it works. So, can you do: delete this; in a member function, then return, to free up the memory? Seems to me it should work...

Regards, Ray L.

Internally to an object the destructor is responsible for freeing any dynamic memory that was allocated with new, alloc, malloc,.... during the lifetime of the object. As well as any other cleanup operations required such as dumping data to a file,.......

The destructor of the object is automatically called when the object goes out of scope such as when a function ends or when you explicitly delete a dynamically created object.

In C++ a destructor has the same name as the class except with a tilde character and no return value.

So here is an example:

class CMyClass
{
    public:
        CMyClass();// Constructor
        ~CMyClass();
};
}

RayLivingston: Would that work? No doubt a strange thing to want to do, but I have an application where it would be quite handy - once the object has done its job, it needs to be deleted, but I don't want to hang onto a reference to it while it works. So, can you do: delete this; in a member function, then return, to free up the memory? Seems to me it should work...

Regards, Ray L.

isn't this more easily done through managing its scope or calling a function?

void someFunction()
{
  // ... do my stuff
  
  // onto the object's turn
  {
    MyClass myObject();

    // ... doing MyClass stuff here 
  } // bye bye class
  
  //doing other stuff


}

otherwise you could look at creating a move constructor that initializes an empty instance of your class and then swaps it with the instance you were working with...

// move constructor uses Rvalue reference:
MyClass(MyClass&& other) : someValue(0), somePtrValue(nullptr){ // Zero initialize the instance 
  swap(other);  // swap is a defined method
}
MyClass v1(someArgs)

// ...

MyClass v2(move(v1));

I've not tried this yet (on arduino 1.8.2) so I'm not sure if the current IDE/gcc supports the move() constructor but it is a C++ '11 feature.

I can't even pretend to understand most of that.... But I also think maybe you missed some important points. I call the constructor. The constructor spins off a separate thread that actually handles the message send/receive, by doing nothing more than executing a member function of the object. The main task never needs to even look at the object after calling the constructor. So, having the thread that is handling the send/receive delete the object once the send/receive is done is the most efficient way of handling things. No need to keep a list of objects, keep checking if they're idle and deleting them. The main thread creates one or more objects, and can then forget they ever existed, and they will clean up after themselves.

At the moment, this is working perfectly, using a pure static object, but I'd like to extend it to non-static objects, and can't see any reason why it should not work.

Regards, Ray L.

BulldogLowell: otherwise you could look at creating a move constructor

From the linked page:

Move constructors typically "steal" the resources held by the argument (e.g. pointers to dynamically-allocated objects, file descriptors, TCP sockets, I/O streams, running threads, etc.) rather than make copies of them, and leave the argument in some valid but otherwise indeterminate state. For example, moving from a std::string or from a std::vector may result in the argument being left empty.

Frankly, the last thing you want in an embedded environment is indeterminate states. The only thing worse is indeterminate searches (new/delete) and not limiting the number of instances (or not knowing the limit through analysis).

Somehow, the OP thinks there is extra tracking required for an instance that must have its suicidal method invoked. But you can't call the method unless you have the instance -- obviously it has been tracked up to this point. You might as well use the orthodox delete obj in the caller, instead of delete this in the object's method.

Even better, use a pool (this or this), like Coding Badly and I suggested. This is a Garbage Collection problem, and has been solved in many differernt ways, all of them better than using delete this.

Whatevs.

I create the client object, which spins off a separate thread to handle the communications, and immediately returns to the caller.

which OS do you use on your arduino?

RayLivingston: ...having the thread that is handling the send/receive delete the object...

sorry, what Arduino are you using?