www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - "this" reference not working?

reply orgoton <orgoton mindless.com> writes:
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?
Apr 07 2007
parent reply Max Samukha <samukha voliacable.com> writes:
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.
Apr 07 2007
parent reply OP <OP nothing.com> writes:
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.
Apr 08 2007
parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"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(); }
Apr 08 2007