In my first foray into classes this weekend, I came across the notion of a class destructor.
When and why would I want to destroy an instance?
In my first foray into classes this weekend, I came across the notion of a class destructor.
When and why would I want to destroy an instance?
Destructors give you a way to shut things down cleanly, close "files", free dynamically allocated memory, etc. In many cases, they are not required to do anything.
Regards,
Ray L.
The destructor does not destroy the instance. You destroy the instance, one way or another, and the destructor (if there is one) is then called. As Ray said, this gives you a chance to free memory, for example. In the case of the String class, which dynamically allocates memory as the string grows in size, the destructor is when it gets freed.
Example:
void loop ()
{
if (true)
{
String s;
s = "Hello, world";
} // <-- destructor for "s" called now
}
And from the String class:
String::~String()
{
free(buffer);
}
As expected, it frees the memory used by the string.
The destructor would be called when the class instance goes out of scope, or if it is dynamically allocated with "new" the destructor is called when "delete" is called on that instance.
When and why would I want to destroy an instance?
To answer your question generally, on the arduino, you probably wouldn't.
But in applications on other platforms, you often want to destroy instances of class objects.
Suppose you are a waiter in a restaurant, and your class object is "a page in waiter's notebook".
When a table of customers enter the restaurant, you allocate a new page in the notebook for their orders. You take the order, take any additional orders. After they eat, pay, and leave, you tear that page out of the notebook and chuck it in the bin. That's destroying an instance.
Yes, but the waiter does that, not the page.
Just to reiterate. The destructor does not go around destroying things, like the Terminator.
It is a function that is called when the instance is destroyed by some other event.
Ok thanks... so follow-up question then has to be, how does one destroy an instance?
Let's say I have an instance of a class doing some blinking-without-delay and I want to kill that blinking, perhaps on sensing a hardware switch. On reading the switch and finding it low, I could make the relevant pins low thereby turning the leds off but then I guess the instance would still exist. Would it buy me anything to destroy it?, and if so, how?
As Nick said, the destructor for any instance of a class will be called when you either explicitly call delete on an instance created with new, or when the last reference to the instance goes out of scope.
Regards,
Ray L.
Ah ok so seems I need to read up on "delete" and "new".
Since a line like this:
BWOD myBWOD;
... does not use "new" I suppose it's not a candidate to kill later with "delete".
At least I know now what I should be looking for to read: "delete" and "new".
Thanks.
void loop ()
{
BWOD myBWOD;
// ...
}
myBWOD goes out of scope (is destroyed) when you exit loop.
However:
BWOD * myBWOD;
void setup ()
{
myBWOD = new BWOD;
}
Now myBWOD persists until such time as you delete it:
delete myBWOD;
Ok thanks, now it seems I have to get my mind round pointers since that's what the * is I think? Maybe I should quit while I'm ahead 8)
Correction...
RayLivingston:
...or whenthe last reference tothe instance goes out of scope.
In regards to destruction, the compiler does not care about references. The classic example is returning a pointer / reference to a stack instance. The instance is destroyed despite the fact that a pointer / reference to the instance is still in play.
@JimboZA, what that means to you, the software developer, is that you have to be aware of who will destroy an instance (you or the compiler) and when it will happen. Essentially you are responsible for ensuring the correct lifetime of an instance.
Ok thanks... so follow-up question then has to be, how does one destroy an instance?
In C++ there are four places an instance can reside. 1. Global. 2. Stack. 3. Heap. 4. One we won't talk about.
A global instance is created by initialization code before main is called then destroyed after main returns. In the microcontroller world, returning from main is a bad idea so destruction is essentially irrelevant.
A stack instance is created when the scope starts (typically the beginning of a function) then destroyed when the scope ends (typically the end of a function).
A heap instance is entirely under your control using the new and delete operators.
Let's say I have an instance of a class doing some blinking-without-delay and I want to kill that blinking, perhaps on sensing a hardware switch. On reading the switch and finding it low, I could make the relevant pins low thereby turning the leds off but then I guess the instance would still exist. Would it buy me anything to destroy it?, and if so, how?
Assuming the instance is on the heap, destroying it would release that memory. However, if you do not need that memory for other purposes and the blinking-class-instance will be needed again in the future then destroying the instance serves no purpose. In that case, you would be better served by the class supporting on / off (or enable / disable; or begin / end; or whatever opposing traits suit your fancy).
Thanks for the replies gents: this is getting a bit way too deep for me as a hobbyist. I'll mark the thread answered, and perhaps re-kindle it one day if and when it becomes a requirement to manage instances correctly.
That's not to say I'm not grateful for the detailed replies, but your efforts are probably better spent answering threads with more immediate impact on the OPs' success.
- One we won't talk about.
He-who-will-not-be-named, eh?
It might be worth mentioning that classes can reside inside other classes, so if class A contains an instance of class B, then class B will be created/destroyed along with class A.
And just as a word of warning, although new/delete on the Arduino basically call malloc/free, they are not the same. If you malloc some memory and put a class in that memory, the constructor is not called, nor is the destructor if you free that memory.
JimboZA:
this is gettinga bitway too deep for me as a hobbyist
In the Arduino world, especially for someone just starting with object oriented programming, the best course is to make all instances global. Then you don't need to manage them. The construction is handled before setup is called and destruction never occurs.
...your efforts are probably better spent answering threads with more immediate impact on the OPs' success.
I disagree. There is a dearth of material for Arduino object oriented programming and the two go very well together. At this point, any discussion combining the two is worth having.
But I understand your need to digest.
It is seldom used, is rarely worth the risks, and would push @JimboZA a bit closer to the edge. So definitely he-who-will-not-be-named.
JimboZA:
That's not to say I'm not grateful for the detailed replies, but your efforts are probably better spent answering threads with more immediate impact on the OPs' success.
The "will you do my homework for me" threads?
Oh, I am so very grateful the U.S. is on summer break.
Yeah, probably... I didn't think of that.