prefer polymorphism on existing destructor over custom destructor method
This commit is contained in:
parent
055cbc85de
commit
e0789366e7
3 changed files with 35 additions and 9 deletions
|
|
@ -3231,6 +3231,30 @@ destroyed together. Destroying one without destroying the other will
|
||||||
likely cause your program to segfault.
|
likely cause your program to segfault.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Also note that due to the proxy implementation, the <tt>DESTROY()</tt>
|
||||||
|
method on directors can be called for several reasons, many of which
|
||||||
|
have little to do with the teardown of an object instance. To help
|
||||||
|
disambiguate this, a second argument is added to the <tt>DESTROY()</tt>
|
||||||
|
call when a C++ director object is being released. So, to avoid running
|
||||||
|
your clean-up code when an object is not really going away, or after it
|
||||||
|
has already been reclaimed, it is suggested that custom destructors in
|
||||||
|
Perl subclasses looks something like:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="targetlang">
|
||||||
|
<pre>
|
||||||
|
sub DESTROY {
|
||||||
|
my($self, $final) = @_;
|
||||||
|
if($final) {
|
||||||
|
# real teardown code
|
||||||
|
}
|
||||||
|
shift->SUPER::DESTROY(@_);
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<H3><a name="Perl5_nn51"></a>31.11.4 Exception unrolling</H3>
|
<H3><a name="Perl5_nn51"></a>31.11.4 Exception unrolling</H3>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,9 @@ require_ok('director_finalizer');
|
||||||
{
|
{
|
||||||
package MyFoo;
|
package MyFoo;
|
||||||
use base 'director_finalizer::Foo';
|
use base 'director_finalizer::Foo';
|
||||||
sub DIRECTOR_DESTROY { my($self) = @_;
|
sub DESTROY { my($self, $final) = @_;
|
||||||
$self->orStatus(2);
|
$self->orStatus(2) if $final;
|
||||||
|
shift->SUPER::DESTROY(@_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1529,11 +1529,11 @@ public:
|
||||||
Delete(get_attr);
|
Delete(get_attr);
|
||||||
|
|
||||||
Printv(pm, "sub FETCH {\n", tab4, "my ($self,$field) = @_;\n", tab4, "my $member_func = \"swig_${field}_get\";\n", tab4,
|
Printv(pm, "sub FETCH {\n", tab4, "my ($self,$field) = @_;\n", tab4, "my $member_func = \"swig_${field}_get\";\n", tab4,
|
||||||
"if (not $self->can(\"$member_func\")) {\n", tab4, tab4, "my $h = ", cmodule, "::", mrename, "($self);\n", tab4, tab4,
|
"if (not $self->can($member_func)) {\n", tab8, "my $h = ", cmodule, "::", mrename, "($self);\n", tab8, "return $h->{$field} if $h;\n",
|
||||||
"return $h->{$field} if $h;\n", tab4, "}\n", tab4, "return $self->$member_func;\n", "}\n", "\n", "sub STORE {\n", tab4,
|
tab4, "}\n", tab4, "return $self->$member_func;\n", "}\n", "\n", "sub STORE {\n", tab4, "my ($self,$field,$newval) = @_;\n", tab4,
|
||||||
"my ($self,$field,$newval) = @_;\n", tab4, "my $member_func = \"swig_${field}_set\";\n", tab4,
|
"my $member_func = \"swig_${field}_set\";\n", tab4, "if (not $self->can($member_func)) {\n", tab8, "my $h = ", cmodule, "::", mrename,
|
||||||
"if (not $self->can(\"$member_func\")) {\n", tab4, tab4, "my $h = ", cmodule, "::", mrename, "($self);\n", tab4, tab4,
|
"($self);\n", tab8, "return $h->{$field} = $newval if $h;\n", tab4, "}\n", tab4, "return $self->$member_func($newval);\n", "}\n", NIL);
|
||||||
"return $h->{$field} = $newval if $h;\n", tab4, "}\n", tab4, "return $self->$member_func($newval);\n", "}\n", NIL);
|
|
||||||
Delete(mrename);
|
Delete(mrename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2493,8 +2493,9 @@ public:
|
||||||
String *mangle = SwigType_manglestr(ptype);
|
String *mangle = SwigType_manglestr(ptype);
|
||||||
|
|
||||||
Printv(body, tab4, "dSP;\n", tab4, "SV *self = SWIG_NewPointerObj(SWIG_as_voidptr(this), SWIGTYPE", mangle, ", SWIG_SHADOW);\n", tab4, "\n", tab4,
|
Printv(body, tab4, "dSP;\n", tab4, "SV *self = SWIG_NewPointerObj(SWIG_as_voidptr(this), SWIGTYPE", mangle, ", SWIG_SHADOW);\n", tab4, "\n", tab4,
|
||||||
"sv_bless(self, gv_stashpv(swig_get_class(), 0));\n", tab4, "ENTER;\n", tab4, "SAVETMPS;\n", tab4, "PUSHMARK(SP);\n", tab4, "XPUSHs(self);\n",
|
"sv_bless(self, gv_stashpv(swig_get_class(), 0));\n", tab4, "ENTER;\n", tab4, "SAVETMPS;\n", tab4, "PUSHMARK(SP);\n", tab4,
|
||||||
tab4, "PUTBACK;\n", tab4, "call_method(\"DIRECTOR_DESTROY\", G_EVAL | G_VOID);\n", tab4, "FREETMPS;\n", tab4, "LEAVE;\n", NIL);
|
"XPUSHs(self);\n", tab4, "XPUSHs(&PL_sv_yes);\n", tab4, "PUTBACK;\n", tab4, "call_method(\"DESTROY\", G_EVAL | G_VOID);\n", tab4,
|
||||||
|
"FREETMPS;\n", tab4, "LEAVE;\n", NIL);
|
||||||
|
|
||||||
Delete(mangle);
|
Delete(mangle);
|
||||||
Delete(ptype);
|
Delete(ptype);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue