Insert array into an AA

nrgyzer nrgyzer at gmail.com
Fri Aug 19 08:22:37 PDT 2011


== Auszug aus Steven Schveighoffer (schveiguy at yahoo.com)'s Artikel
> On Thu, 18 Aug 2011 06:47:32 -0400, nrgyzer <nrgyzer at gmail.com>
wrote:
> > == Auszug aus Robert Clipsham (robert at octarineparrot.com)'s
Artikel
> >> On 16/08/2011 20:17, nrgyzer wrote:
> >> > Hi everyone,
> >> >
> >> > I've the following:
> >> >
> >> > private static ubyte[][2][hash_t] classInstances;
> >> >
> >> > this() {
> >> >
> >> >     classInstances[toHash()] = new ubyte[2]; // does not work
> >> >
> >> > }
> >> >
> >> > I want insert every class instance into the hashmap. Every
class
> >> > instance should be contained in the map after the constructor
was
> >> > called. When I compile my code, I get "Error: cannot implicitly
> >> > convert expression (new ubyte[](2u)) of type ubyte[] to ubyte[]
[]"
> >> > which is logical. But is there any way to insert every
instance into
> >> > the array and define the array/map for this entry?
> >> >
> >> > Thanks in advance!
> >> Is there any particular reason you're using ubyte[][2][hash_t]
there? To
> >> keep a reference to each instance simply use:
> >> ----
> >> class MyClass {
> >>      static MyClass[] classInstances;
> >>      this() {
> >>          classInstances ~= this;
> >>      }
> >> }
> >> ----
> >> If you in fact want to have a hashmap indexed by the instances
with
> >> values of type ubyte[][2], you can do this:
> >> ----
> >> class MyClass {
> >>      static ubyte[][2][MyClass] classInstances;
> >>      this() {
> >>          classInstances[this] = new ubyte[][2];
> >>      }
> >> }
> >> ----
> >> The problem in your original code is that you were using = new
ubyte[2]
> >> rather than = new ubyte[][2]. Hope this helps.
> >
> > Ok, that works - thx.
> >
> > @Steve: I'll delete the entries from the map, but what's about
> > overriding the toHash()-function and return a simply int value?
> If two instances return the same hash value (as is easily possible,
but
> maybe not for your context), then a collision occurs.  Then opCmp
is used
> to determine if they are actually identical.
> If you use hash_t as your key, then only one object is stored in
the map,
> the other is simply overwritten.
> > I also need this map-structure for further steps in my
application. I's
> > possible to change it to
> >
> > ubyte[][hash_t] classInstancesOne; // or ubyte[][MyClass]
> > ubyte[][hash_t] classInstancesTwo; // or ubyte[][MyClass]
> >
> > but I thought one map for the same sense is better.
> ubyte[][Object] should work for all class types.
> > Btw: I've two classes where one inherits:
> >
> > class MyClassOne {
> >
> >    protected {
> >       static __gshared {
> >          uint counter;
> >          uint[MyClassOne] fixedData;
> >       }
> >       uint otherData;
> >
> >       this(uint d) {
> >          otherData = d;
> >       }
> >    }
> >
> >    this() {
> >       fixedData[this] = ++counter;
> >    }
> >
> >    @property ref {
> >       uint myPropOne() { return fixedData[this]; }
> >       uint myPropTwo() { return otherData; }
> >    }
> >
> > }
> >
> > class MyClassTwo : MyClassOne {
> >
> >    shared(MyClassOne) supInstance;
> >
> >    this(uint d, MyClassOne mco) {
> >       super(d);
> >       supInstance = mco;
> >    }
> >
> >    override ref alias supInstance.myPropOne myPropOne;
> >
> > }
> >
> > When I create an instance of MyClassOne and call myPropOne on it,
I get
> > "1". When I'm using this instance to create an instance of
> > MyClassTwo and call myPropOne, I get "0". Is there anything I'm
doing
> > wrong?
> That crazy override ref alias line, I have no idea what you're doing
> there.  For sure, override ref is not needed.
> I'm surprised all of this compiles.
> > What I'm trying to do is: One super-class which contains some
fixed data
> > (not inheritable) and some data which are different for each
> > class.
> Note that protected does not prevent MyClassTwo from changing it.
> Also note that even though you've only created one instance of
MyClassOne,
> every MyClassTwo instance is a MyClassOne (and calls MyClassOne's
> constructor).  I think you have applied the wrong techniques to
solving
> your design.  Without knowing further your design/context, I can't
really
> help.
> -Steve

I'm working on a game where the player can build different buildings.
There are some general building-structures which defines the costs to
build it and some other things, but the name of each building can be
modified by the player. So, each building can have it's own name, but
the costs to build are always the same for each building.
To prevent the redefinition of all the property-methods, I want
redirect the properties of a simple building-property to it's
building structure. For example:

class BuildingShell {

   private float[BuildingShell] pCostsToBuild;

   protected {
      string pName;
      this(string name) {
         pName = name;
      }
   }

   this(string name, float costs) {
      pName = name;
      pCostsToBuild[this] = costs;
   }

   @property {
      ref float costsToBuild() { return pCostsToBuild[this]; }
      string name() { return pName; }
   }

}

class Building : BuildingShell {

   shared(BuildingShell) pShell;

   this(BuldingShell bs, string name) {
      super(name);
      pShell = cast(shared) bs;
   }

   override @property pShell.costsToBuild costsToBuild;

}

All instances of BuildingShell will be loaded from a stream, so I
need the ref-keyword in the properties. Because of multi-threading I
also need a shared BuildingShell in the Building-class.


More information about the Digitalmars-d-learn mailing list