Thread overview
"this" reference not working?
Apr 07, 2007
orgoton
Apr 07, 2007
Max Samukha
Apr 08, 2007
OP
April 07, 2007
In my program I have these classes

---------------------------------------
module entity;
import indexes;

enum EntType : ubyte
{Pawn, Tower, Queen, Other}

class Entity{
	this()
	{
		index[this.type].add(this);
	}
	~this()
	{
		index[this.type].remove(this);
	}
	public static const EntType type=EntType.Other;
}
-----------------------------------------
The module indexes keeps track of how many and which objects I have created thus far so
that I can process them sequentially. In order to increase search speed, I created an
array of indexes, one for each entity type.
The index has a .has(Entity target) method that checks if target is indexed.

-----------------------------------
module pawn;
import entity;

class Pawn:Entity
{
	this()
	{
		assert(this.type==EntType.Pawn);
		super();
		assert(index[this.type].has(this), "Pawn not correctly indexed"); //this fails
	}
	~this()
	{
		//super destructor gets called automagically, no need to remove myself from the index
	}
	public static const EntType type=EntType.Pawn;
}
-----------------------------------------

Add some other classes for the remaining EntType entries. Because Entity _may_ be instaciated it must have an index.add and because of overloaded ctors (such as this(coordinates) that I did not copy) the super() is _always_ called and consequently I have entities indexed on the wrong indexes.

On the D documentation, it states:
"Within a non-static member function, this resolves to a reference to the object for which the function was called."
The example works fine.

Obviously, this isn't working for ctors. Is this a bug? If not, any suggestions as to I might get my prog working?

Also, on a side note, in order to have variables read-only, I declare them has private or protected and then create a method like "getVar()". Why isn't there a keyword like "readonly type var" in which var is read only outside the scope of the class?
April 07, 2007
On Sat, 07 Apr 2007 07:34:17 -0400, orgoton <orgoton@mindless.com> wrote:

>In my program I have these classes
>
>---------------------------------------
>module entity;
>import indexes;
>
>enum EntType : ubyte
>{Pawn, Tower, Queen, Other}
>
>class Entity{
>	this()
>	{
>		index[this.type].add(this);
>	}
>	~this()
>	{
>		index[this.type].remove(this);
>	}
>	public static const EntType typeEntType.Other;
>}
>-----------------------------------------
>The module indexes keeps track of how many and which objects I have created thus far so
>that I can process them sequentially. In order to increase search speed, I created an
>array of indexes, one for each entity type.
>The index has a .has(Entity target) method that checks if target is indexed.
>
>-----------------------------------
>module pawn;
>import entity;
>
>class Pawn:Entity
>{
>	this()
>	{
>		assert(this.type==EntType.Pawn);
>		super();
>		assert(index[this.type].has(this), "Pawn not correctly indexed"); //this fails
>	}
>	~this()
>	{
>		//super destructor gets called automagically, no need to remove myself from the index
>	}
>	public static const EntType type=EntType.Pawn;
>}
>-----------------------------------------
>
>Add some other classes for the remaining EntType entries. Because Entity _may_ be instaciated it must have an index.add and because of overloaded ctors (such as this(coordinates) that I did not copy) the super() is _always_ called and consequently I have entities indexed on the wrong indexes.
>
>On the D documentation, it states:
>"Within a non-static member function, this resolves to a reference to the object for which the function was called."
>The example works fine.
>
>Obviously, this isn't working for ctors. Is this a bug? If not, any suggestions as to I might get my prog working?

You could use a virtual function to solve this:

class Entity{
	this()
	{
		 index[this.type].add(this);
	}
	~this()
	{
		index[this.type].remove(this);
	}
	EntType type()
	{
		 return EntType.Other;
	}
}

class Pawn:Entity
{
	this()
	{
		assert(this.type==EntType.Pawn);
		super();
		assert(index[this.type].has(this), "Pawn not correctly
indexed"); //this fails
	}
	~this()
	{
		//super destructor gets called automagically, no need
to remove myself from the index
	}

	override EntType type()
	{
		return EntType.Pawn;
	}
}

-------------------
Or using ClassInfo:

class Entity{
	this()
	{
		index[this.classinfo].add(this);
	}
	~this()
	{
		index[this.classinfo].remove(this);
	}
}

class Pawn:Entity
{
	this()
	{
		super();
		assert(index[this.classinfo].has(this), "Pawn not
correctly indexed"); //this fails
	}
	~this()
	{
		//super destructor gets called automagically, no need
to remove myself from the index
	}
}

There may be a better solution.



April 08, 2007
Max Samukha Wrote:

> On Sat, 07 Apr 2007 07:34:17 -0400, orgoton <orgoton@mindless.com> wrote:
> 
> >In my program I have these classes
> >
> >---------------------------------------
> >module entity;
> >import indexes;
> >
> >enum EntType : ubyte
> >{Pawn, Tower, Queen, Other}
> >
> >class Entity{
> >	this()
> >	{
> >		index[this.type].add(this);
> >	}
> >	~this()
> >	{
> >		index[this.type].remove(this);
> >	}
> >	public static const EntType typeEntType.Other;
> >}
> >-----------------------------------------
> >The module indexes keeps track of how many and which objects I have created thus far so
> >that I can process them sequentially. In order to increase search speed, I created an
> >array of indexes, one for each entity type.
> >The index has a .has(Entity target) method that checks if target is indexed.
> >
> >-----------------------------------
> >module pawn;
> >import entity;
> >
> >class Pawn:Entity
> >{
> >	this()
> >	{
> >		assert(this.type==EntType.Pawn);
> >		super();
> >		assert(index[this.type].has(this), "Pawn not correctly indexed"); //this fails
> >	}
> >	~this()
> >	{
> >		//super destructor gets called automagically, no need to remove myself from the index
> >	}
> >	public static const EntType type=EntType.Pawn;
> >}
> >-----------------------------------------
> >
> >Add some other classes for the remaining EntType entries. Because Entity _may_ be instaciated it must have an index.add and because of overloaded ctors (such as this(coordinates) that I did not copy) the super() is _always_ called and consequently I have entities indexed on the wrong indexes.
> >
> >On the D documentation, it states:
> >"Within a non-static member function, this resolves to a reference to the object for which the function was called."
> >The example works fine.
> >
> >Obviously, this isn't working for ctors. Is this a bug? If not, any suggestions as to I might get my prog working?
> 
> You could use a virtual function to solve this:
> 
> class Entity{
> 	this()
> 	{
> 		 index[this.type].add(this);
> 	}
> 	~this()
> 	{
> 		index[this.type].remove(this);
> 	}
> 	EntType type()
> 	{
> 		 return EntType.Other;
> 	}
> }
> 
> class Pawn:Entity
> {
> 	this()
> 	{
> 		assert(this.type==EntType.Pawn);
> 		super();
> 		assert(index[this.type].has(this), "Pawn not correctly
> indexed"); //this fails
> 	}
> 	~this()
> 	{
> 		//super destructor gets called automagically, no need
> to remove myself from the index
> 	}
> 
> 	override EntType type()
> 	{
> 		return EntType.Pawn;
> 	}
> }
> 
> -------------------
> Or using ClassInfo:
> 
> class Entity{
> 	this()
> 	{
> 		index[this.classinfo].add(this);
> 	}
> 	~this()
> 	{
> 		index[this.classinfo].remove(this);
> 	}
> }
> 
> class Pawn:Entity
> {
> 	this()
> 	{
> 		super();
> 		assert(index[this.classinfo].has(this), "Pawn not
> correctly indexed"); //this fails
> 	}
> 	~this()
> 	{
> 		//super destructor gets called automagically, no need
> to remove myself from the index
> 	}
> }
> 
> There may be a better solution.
> 
> 
> 

Nope, because you still make use of "this" pointer. I need an option that wouldn't need the pointer or in which the pointer correctly points to the caller of the contructor.
April 08, 2007
"OP" <OP@nothing.com> wrote in message news:evb2c0$2bel$1@digitalmars.com...
>
> Nope, because you still make use of "this" pointer. I need an option that wouldn't need the pointer or in which the pointer correctly points to the caller of the contructor.

"this" is working just fine.  Believe me, I think people would have had problems by now if it wasn't.

The thing is that you can't have "virtual members."  You can't override a data member and have it be referenced through a class instance pointer virtually.  I.e. this (which is basically what you're doing) won't work:

class A
{
    static int x = 5;

    void printX()
    {
        // this x references A.x, regardless of what type 'this' is
        writefln(x);
    }
}

class B : A
{
    static int x = 10;

    override void printX()
    {
        super.printX();
    }
}

void main()
{
    A a = new A();
    // Prints 5
    a.printX();
    B b = new B();
    // Also prints 5
    b.printX();
}

"this.x" in any method (including the constructor) of A will always refer to A.x, because you're allowed to access static members through class instances.

This has to be done using a virtual method, i.e.

class A
{
    static int x = 5;

    void printX()
    {
        // now this uses a virtual call
        writefln(getX());
    }

    int getX()
    {
        return x;
    }
}

class B : A
{
    static int x = 10;

    override void printX()
    {
        super.printX();
    }

    override int getX()
    {
        // this is one of B's methods, so it returns B.x
        return x;
    }
}

void main()
{
    A a = new A();
    // Prints 5
    a.printX();
    B b = new B();
    // Now prints 10
    b.printX();
}