www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Beginner: How does an object delete itself?

reply "nobody" <somebody somewhere.com> writes:
Hello. I just started using OOP and had a question.

I have something like this:

class Foo{
..
    private void deleteMyself()
    {
        this.delete;
        foo.length--;
    }
..
}

Foo[] foo;

But this obviously doesn't work.
The problem is, how do I know what position in the array the object is, and 
how do I delete it?
I don't want empty elements in my array. 
Sep 21 2008
next sibling parent reply ylixir <ylixir gmail.com> writes:
nobody wrote:
 Hello. I just started using OOP and had a question.
 
 I have something like this:
 
 class Foo{
 ..
     private void deleteMyself()
     {
         this.delete;
         foo.length--;
     }
 ..
 }
 
 Foo[] foo;
 
 But this obviously doesn't work.
 The problem is, how do I know what position in the array the object is, and 
 how do I delete it?
 I don't want empty elements in my array. 
 
 

you could do some wizardry to get something like that to work, but it sounds like such an awkward situation to be at in the first place. maybe if you posted a little more context around that bit, someone could help you find a design pattern that would eliminate the need to do that altogether. honestly, in most cases, something like that wouldn't be a good idea. what if the class was used later in something other than an array?
Sep 21 2008
parent "nobody" <somebody somewhere.com> writes:
I'm still only a beginner, but this class is only used in one array ;)


"ylixir" <ylixir gmail.com> wrote in message 
news:gb5pv5$2f87$1 digitalmars.com...
 nobody wrote:
 Hello. I just started using OOP and had a question.

 I have something like this:

 class Foo{
 ..
     private void deleteMyself()
     {
         this.delete;
         foo.length--;
     }
 ..
 }

 Foo[] foo;

 But this obviously doesn't work.
 The problem is, how do I know what position in the array the object is, 
 and how do I delete it?
 I don't want empty elements in my array.

you could do some wizardry to get something like that to work, but it sounds like such an awkward situation to be at in the first place. maybe if you posted a little more context around that bit, someone could help you find a design pattern that would eliminate the need to do that altogether. honestly, in most cases, something like that wouldn't be a good idea. what if the class was used later in something other than an array?

Sep 21 2008
prev sibling next sibling parent reply "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Sun, 21 Sep 2008 17:15:22 +0200, nobody <somebody somewhere.com> wrote:

 Hello. I just started using OOP and had a question.

 I have something like this:

 class Foo{
 ..
     private void deleteMyself()
     {
         this.delete;
         foo.length--;
     }
 ..
 }

 Foo[] foo;

 But this obviously doesn't work.
 The problem is, how do I know what position in the array the object is,  
 and
 how do I delete it?
 I don't want empty elements in my array.

class Foo { ... private void deleteMySelf() { for (int i = 0; i < foo.length; i++) { if (foo[i] == this) { // If order is not important, copy last element of array to position i // // foo[i] = foo[$-1]; // // If order is important, iterate through rest of array, moving elements one step forward // // while (++i < foo.length) // { // foo[i-1] = foo[i]; // } // foo.length--; } } delete this; } ... } Foo[] foo; -- Simen
Sep 21 2008
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Simen Kjaeraas:
 // If order is important, iterate through rest of array, moving elements one
step forward

I'd like to use the normal D slice syntax for this copying, but you can't, because that syntax can be used only when arrays don't overlap. Bye, bearophile
Sep 21 2008
prev sibling next sibling parent reply "nobody" <somebody somewhere.com> writes:
Thanks, after some Access Violations in my code I got it to work.

But is this not better?

class Foo
{
...
     private void deleteMySelf()
     {
         for (int i = 0; i < foo.length; i++)
         {
             if (foo[i] == this)
             {
                 foo[i] = foo[$-1];

                 foo.length--;

                 delete this;

                 break; // is this still necessary?
             }
         }
     }
...
} 
Sep 21 2008
parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"nobody" wrote
 Thanks, after some Access Violations in my code I got it to work.

 But is this not better?

 class Foo
 {
 ...
     private void deleteMySelf()
     {
         for (int i = 0; i < foo.length; i++)
         {
             if (foo[i] == this)

A warning for the beginner, be careful with ==. Use 'is' to check for identity (i.e. the exact same instance). If you don't, you may end up with segmentation faults: if(foo[i] is this)
             {
                 foo[i] = foo[$-1];

                 foo.length--;

                 delete this;

                 break; // is this still necessary?
             }
         }
     }
 ...
 }

Like others, I think this seems like a bad design. What is wrong with using the garbage collector? And what's wrong with using an external class/function to keep track of the Foo's? If you wanted to change at some point your foo array to another type of container instead of an array, your function wouldn't work, so Foo is stuck being only in an array. -Steve
Sep 21 2008
prev sibling parent Janderson <ask me.com> writes:
Simen Kjaeraas wrote:
 On Sun, 21 Sep 2008 17:15:22 +0200, nobody <somebody somewhere.com> wrote:
 
 Hello. I just started using OOP and had a question.

 I have something like this:

 class Foo{
 ..
     private void deleteMyself()
     {
         this.delete;
         foo.length--;
     }
 ..
 }

 Foo[] foo;

 But this obviously doesn't work.
 The problem is, how do I know what position in the array the object 
 is, and
 how do I delete it?
 I don't want empty elements in my array.

class Foo { ... private void deleteMySelf() { for (int i = 0; i < foo.length; i++) { if (foo[i] == this) { // If order is not important, copy last element of array to position i // // foo[i] = foo[$-1]; // // If order is important, iterate through rest of array, moving elements one step forward // // while (++i < foo.length) // { // foo[i-1] = foo[i]; // } // foo.length--; } } delete this; } ... } Foo[] foo;

Personally I wouldn't add a method to the class to remove it from a list. Why? Because then your coupling the array to that object. Its far better to write a free function to do it: void Remove(inout F[] array, F element) { for (int i=0; i<array.length; ++i) { if (array[i] == element) { array = array[0..i] ~ array[i+1..$]; break; } } } Ok, what the hell, lets make it a template: void Remove(F)(inout F[] array, F element) { for (int i=0; i<array.length; ++i) { if (array[i] == element) { array = array[0..i] ~ array[i+1..$]; break; } } } Now it'll work on any array. Also if your deleting more then one element in an array you can simply iterate backwoods to solve the i shifting to the wrong place problem: for (int i=array.length; --i>=0; ) { if (isTypeLookingFor(array[i])) { array = array[0..i] ~ array[i+1..$]; } } -Joel
Sep 21 2008
prev sibling next sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Sun, 21 Sep 2008 18:31:07 +0200, bearophile <bearophileHUGS lycos.com>  
wrote:

 Simen Kjaeraas:
 // If order is important, iterate through rest of array, moving  
 elements one step forward

I'd like to use the normal D slice syntax for this copying, but you can't, because that syntax can be used only when arrays don't overlap. Bye, bearophile

I guess one could use memmove, if one wanted. But as you say, slices would be neater. -- Simen
Sep 22 2008
prev sibling parent "Tim M" <a b.com> writes:
On Mon, 22 Sep 2008 03:15:22 +1200, nobody <somebody somewhere.com> wrote:

 Hello. I just started using OOP and had a question.

 I have something like this:

 class Foo{
 ..
     private void deleteMyself()
     {
         this.delete;
         foo.length--;
     }
 ..
 }

 Foo[] foo;

 But this obviously doesn't work.
 The problem is, how do I know what position in the array the object is,  
 and
 how do I delete it?
 I don't want empty elements in my array.

By now I assume you understand that was a bad idea but the replies don't seem to go into much detail why. If you have one process and that process is only making use of the initial thread, no other threads are cretaed. Then when this method gets called to delete self and the object is deleted, where doe's the next line of code execution occur? A way to make something like that work would be to have each running in there own thread and then they delete there own thread. If no other threads have a reference to the same object then the garbage collecor cleans up for you. Another way is provide your own delete self which just removes references to itself from other classes and the gc will then clean it up again.
Oct 03 2008