Object arrays in D

simendsjo simendsjo at gmail.com
Tue Apr 10 02:15:12 PDT 2012


On Tue, 10 Apr 2012 10:53:58 +0200, CrudOMatic <crudomatic at gmail.com>  
wrote:

> On Tuesday, 10 April 2012 at 08:05:33 UTC, simendsjo wrote:
>> On Tue, 10 Apr 2012 09:41:28 +0200, CrudOMatic <crudomatic at gmail.com>  
>> wrote:
>>
>>> The D documentation is a little lacking in a lot of areas. I'm needing  
>>> to know an exact way of making arrays of objects.
>>>
>>> For example:
>>>
>>> /* Deck class */
>>> 	// Will be adjusted with the proper cards for each game type
>>> 	class Deck {
>>> 		/* Card count - used to keep track of how many cards are left in the  
>>> deck - when zero, Deck is discarded from the Shoe */
>>> 		int cardCount;
>>> 		/* Cards array - initialized to cardCount elements */
>>> 		Card cards[];
>>> 		
>>> 		/* Constructor */
>>> 		this(int no_cards) {
>>> 			cardCount = no_cards;
>>> 			cards = new Card[cardCount];
>>> 		}
>>> 		
>>> 		/* Destructor */
>>> 		~this() {
>>> 			delete cards;
>>> 		}
>>> 	}
>>>
>>> the cards[] array is meant to be an array of Card objects, and I'm  
>>> initializing it in the constructor as seen above. This hasn't been  
>>> tested yet, but I'm needing to know if this is the correct way of  
>>> doing it - to save headaches later.
>>>
>>> Also, while I'm here, how would you go about moving objects from the  
>>> cards array in the Deck class to another class containing a cards  
>>> array - I'm talking about MOVING them, not COPYING them. I don't want  
>>> any issues with references being destroyed after being moved to  
>>> another class when I happen to destroy an instance of the Deck class.
>>
>> In D, arrays includes the number of elements in the array.
>>
>> Card[] cards;
>> assert(cards.length == 0); // Automatically initialized to 0 elements
>> cards.length = cardCount; // cards gets cardCount of null elements
>> cards.reserve(cardCount); // This just extends the array without  
>> filling with null elements. cards.length stays at 0
>>
>> D includes array slices - a view into an array. This way, you can  
>> reference cards without copying them.
>> auto other = cards[1..$-1]; // all but first and last card
>>
>> I'll let someone else answer the moving part as I'm not sure how that  
>> could be done.
>>
>> The delete statement is going away. You should use clear(cards)  
>> instead. This really isn't needed as Ds GC will take care of it  
>> eventually.
>>
>> Your example could be written as
>>
>> class Deck {
>>   Card[] cards;
>>   @property int cardCount() {
>>     return cards.length;
>>   }
>>   this(int no_cards) {
>>     cards.reserve(no_cards);
>>   }
>> }
>>
>> Arrays are more complicated than they seem at first. I recommend you  
>> read this article: http://dlang.org/d-array-article.html
>>
>> D has a newsgroup, .learn, for beginner questions.
>
> Thanks, I'm not sure if this is what I was after though. Let me explain  
> a little more, and you can tell me if I'm stupid or not.
>
> To make it simple - I have 4 (well more than 4, but trying to get these  
> shored up first) classes, Shoe, Deck, Hand and Card.
>
> The Shoe class contains anywhere from 4 to 8 Deck objects in a Deck  
> array.
>
> The Deck class contains anywhere from 40 to 54 Card objects in a Card  
> array.
>
> The Hand class contains a 2-dimensional array of Card Objects ([2][]),  
> that are to be moved from the Deck array and placed here.
>
> The Card class just contains info on the card in question.
>
> The cardCount property in Deck gets decremented each time a card is  
> dealt from it, until it reaches zero - which then that instance of the  
> Deck object is removed from the Deck array in Shoe - thus why I needed  
> to move instead of just copying or referencing.
>
> The way I'm understanding your solution is that you are treating it just  
> as a normal property instead of a generic object reference count. If  
> not, then I've mistaken what you were meaning. It's merely there to tell  
> me how many objects are left until time to clear() it away.

Not quite sure where you are going with this..

class Deck {
   Card popBack() {
     auto card = cards.popBack(); // get last card. cards.length is  
decremented
     assumeSafeAppend(cards); // now we can add cards to the deck without  
it relocating - not sure if you need this though
     return card;
   }
}

I don't know why you cannot just use a reference. When you stop using a  
Deck, the cards won't be cleaned by the GC as you are referencing Cards  
 from other parts of the program - like Hand.


More information about the Digitalmars-d mailing list