Archived

This topic is now archived and is closed to further replies.

Bakemono

Entity List

Recommended Posts

Bakemono    122
I''ve started working on an rpg and I have come to a huge problem. It needs to handle all kinds of items and world entities, and I want to have them in llists. The problem is that I have a class torch(just an example) that looks like this: class torch { public: void update(); private: bool lit; int fuel; } void torch::update() { if(lit == true) { fuel--; } if(fuel == 0) { lit == false; } } and I have a llist like this: typedef struct { void *data; void *prev; void *next; } LList; and I do this: LList *entitylist; entitylist->prev = NULL; entitylist->next = NULL; entitylist->data = (torch *)malloc(sizeof(torch)); entitylist->data->update(); vc++ says "left of ->update must point to class/struct/union", can someone PLEASE help me. This is VERY important.

Share this post


Link to post
Share on other sites
vladg    122
That''s because LList::data is of type void*. Void* does not know what it points to, it does not know that it actually points to a class with update() method.
Simpliest way to solve this is to typecast LList::data to correct type:

  
((torch*)(entitylist->data))->update();


It is also the wrong way to do it. It won''t solve the problem in the long run. Imagine you add a second object type... umm, beer mug. So, when you traverse your list you won''t know which node points to which object. To solve this you declare a base class with a virtual update() method and inherit all your entities from it:

  
class CEntity
{
public:
virtual void update() = 0;
// = 0 means it''s a pure virtual,

// cannot be instantiated

// can only be used as a base for some other class

};

// torch is an entity

class torch : public CEntity
{
public:
virtual void update();
private:
bool lit;
int fuel;
};

void torch::update(){
if(lit == true) {
fuel--;
}
if(fuel == 0) {
lit == false;
}
};

// CBeerMug is an entity too

class CBeerMug : public CEntity
{
public:
virtual void update();
private:
void Refill() { // code here }

void Sip() { // code here }

private:
long m_lBeerLeft;
};

void CBeerMug::update()
{
if(m_lBeerLeft <= 0)
Refill();

Sip();
}


// both torch and CBeerMug are of type CEntity

// so, if you have a pointer to CEntity

// it can point to any class inherited from

// CEntity, either torch or CBeerMug


CEntity* pEntity = new torch;
pEntity->update();
delete pEntity;
pEntity = NULL;


pEntity = new CBeerMug;
pEntity->update();
delete pEntity;
pEntity = NULL;


This might not compile as is, but it should give you an idea.

You also might want to consider changing next and prev pointers to LList*. Using void* pointer is not type safe, avoid it if you can.

A couple more things:
- make sure you allocate list node before you use it
- you should use new new/delete to allocate/deallocate classes, not malloc/free.

Happy coding!

Share this post


Link to post
Share on other sites
Bakemono    122
first of all, thank you very much for the code. I''m a little new to c++(not C, just c++) and it may take a while before I fully understand what you have told me.

Second, *before* I posted this, I fixed LList to be:

typedef struct {
void *data;
LList *prev;
LList *next;
} LList;

Third, what did you mean by "you should use new new/delete to allocate/deallocate not malloc/free", I don''t know what you are talking about. How do I use new/delete?

Share this post


Link to post
Share on other sites
new and delete are two operators in C++ that replace C''s malloc() and free(). I find they (new and delete) are much better/more reliable/don''t cause as many problems/cause as many access violations as malloc and free.

  
int *foo = new int; // Allocate mem


//use foo here


delete foo; // clear memory



-----------------------------
-cow_in_the_well

''When in doubt, empty your magazine.'' - Murphy''s Combat Law

Share this post


Link to post
Share on other sites