www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Destructors calling sequence

reply "Temtaime" <temtaime gmail.com> writes:
Hi !
http://dpaste.dzfl.pl/53d9a59e

How i can enforce that ~A will be called after ~B ?

I'm writing 3D engine and it's critical to me.

Thanks for yours aid !
Nov 29 2013
next sibling parent "Temtaime" <temtaime gmail.com> writes:
Please, don't advise to call b.destroy.
Nov 29 2013
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Temtaime:

 How i can enforce that ~A will be called after ~B ?
 I'm writing 3D engine and it's critical to me.
The GC doesn't give such guarantees. So you need something manual, or to use RAII, or scope(exit), or some other idea like creating an array of objects to be destroyed, etc. Bye, bearophile
Nov 29 2013
prev sibling next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
In this specific case, you can force a collection at the end of 
main()


void main() {
	auto b = new B;
	a = new A;

	import core.memory;
	GC.collect();
}

The gc runs automatically at the end of the program, but at that 
point, both b and a are gone, so the gc just gets to it as soon 
as it can. Manually calling collect after you're done with b but 
before the program ends (so a is still in use) it should do it in 
order.

But, generally, if you want to rely on destructors at all, you 
have to use structs, or at least destroy(). They might never run 
with classes and the order is undefined - it all depends on when 
and if the GC ever actually grabs it.

Thought a struct at module scope might never run its destructor 
at all...
Nov 29 2013
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 11/29/2013 08:58 AM, Adam D. Ruppe wrote:

 In this specific case, you can force a collection at the end of main()


 void main() {
      auto b = new B;
      a = new A;

      import core.memory;
      GC.collect();
 }
Note that the OP requires the unusualy destruction order: b first. In any case, these objects can be destroyed without destroy anyway. mixin("dest" ~ /* :p */ "roy(a);"); Ali
Nov 29 2013
prev sibling parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Friday, 29 November 2013 at 16:48:58 UTC, Temtaime wrote:
 Hi !
 http://dpaste.dzfl.pl/53d9a59e

 How i can enforce that ~A will be called after ~B ?

 I'm writing 3D engine and it's critical to me.

 Thanks for yours aid !
It is impossible to do this directly given current gc implementation, but you can do something like that: class A { bool reset; void delegate dtor(); ~this() { if (!reset) dtor(); } } class B { A a; bool run; ~this() { if (!run) a.reset = true; run = true; } } A a = new A; B b = new B; b.a = a; b.a.dtor = & b.__dtor;
Nov 29 2013
next sibling parent "Temtaime" <temtaime gmail.com> writes:
I see.
Thanks for all for yours replies !
Nov 29 2013
prev sibling parent "Michael" <pr m1xa.com> writes:
 class A
 {
    bool reset;
    void delegate dtor();
    ~this()
    {
       if (!reset)
          dtor();
    }
 }

 class B
 {
    A a;
    bool run;
    ~this() { if (!run) a.reset = true; run = true; }
 }

 A a = new A;
 B b = new B;
 b.a = a;
 b.a.dtor = & b.__dtor;
relying on to "bool reset" it's no good idea. In this case a manual memory management - good choice.
Nov 30 2013