Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is object destructor not called when script terminates?

I have a test script like this:

package Test;
sub new { bless {} }
sub DESTROY { print "in DESTROY\n" }

package main;
my $t = new Test;
sleep 10;

The destructor is called after sleep returns (and before the program terminates). But it's not called if the script is terminated with Ctrl-C. Is it possible to have the destructor called in this case also?

like image 206
planetp Avatar asked Apr 13 '10 11:04

planetp


People also ask

What happens when destructor is not called?

There are two reasons that your destructors aren't being called, one is as kishor8dm pointed out that you are using the operator "new" and because of that the "delete" command must be called explicitly.

What happens if destructor is not called in C++?

A destructor is only an automatic function that activates when the object go out of scope. There is no drawbacks of not using it, if you do not need that function.

Is destructor called before return?

The destructor is called after the last statement of the scope containing the variable which is an instance of a class. Save this answer.

Are destructors called on Sigint?

No, by default, most signals cause an immediate, abnormal exit of your program. However, you can easily change the default behavior for most signals. If you run this program and press control-C, you should see the word "destructor" printed.

Do you need to call a destructor?

No. You never need to explicitly call a destructor (except with placement new ). A class's destructor (whether or not you explicitly define one) automagically invokes the destructors for member objects. They are destroyed in the reverse order they appear within the declaration for the class.


2 Answers

As Robert mentioned, you need a signal handler.
If all you need is the object destructor call, you can use this:

$SIG{INT} = sub { die "caught SIGINT\n" };.

like image 85
Eugene Yarmash Avatar answered Sep 23 '22 14:09

Eugene Yarmash


You'll have to set up a signal handler.

package Test;
sub new { bless {} }
sub DESTROY { print "in DESTROY\n" }

package main;

my $terminate = 0;

$SIG{INT} = \&sigint;

sub sigint { $terminate = 1; }

my $t = new Test;

while (1) {
    last if $terminate;
    sleep 10;
}

Something along these lines. Then in your main loop just check $terminate and if it's set exit the program normally.

What happens is that the cntl-c interrupts the sleep, the signal handler is called setting $terminate, sleep returns immediately, it loops to the top, tests $terminate and exits gracefully.

like image 40
Robert S. Barnes Avatar answered Sep 22 '22 14:09

Robert S. Barnes