I fixed a problem...Now, what exactly did I just do?

N

Narf the Mouse

I'm currently working on a roguelike as an excercise in learning c++.
Anyway, I've set up a script parser to check a text file to find out
how many races there are, then dynamically alocate an array 'RaceClass
* RaceList = new RaceClass[NumRaces];'
Now, upon array creation, each member of that array also gets a
dynamically created list of twenty parent class body parts:
' BodyClass * BodyPart;
RaceClass () {
BodyPart = new BodyClass[20];
};'
Then the text file for each race is parsed to see how many of different
types of limbs that race has, and limbs are alocated.
Now, this works:
' if ( fieldData[1] == "Arm" ) {
NewBodyPart = new ArmClass;
CurRace.BodyPart[t] = (const BodyClass&)
*NewBodyPart;
};'
I know this because the constructer for the 'ArmClass' alocated the
right variable.
This doesn't:
' if ( fieldData[1] == "Leg" ) {
NewBodyPart = new LegClass;
CurRace.BodyPart[t] = (BodyClass*) NewBodyPart;
};'
I know this because Dev cpp returns an error on it.
Specifically:
191 no match for 'operator=' in '*(CurRace->RaceClass::BodyPart +
(+(((unsigned int)t) * 12u))) = NewBodyPart'
191 candidates are: BodyClass& BodyClass::eek:perator=(const BodyClass&)

The second is what I used to create the fix.

My guess is, it gets a pointer to NewBodyPart, then turns the pointer
into a reference for BodyClass - But I'm a newbie and would appreciate
an explanation of what I just did. Thanks.
 
A

Alf P. Steinbach

* Narf the Mouse:
I'm currently working on a roguelike

What's a "roguelike"? I'd guess something related to a game?

as an excercise in learning c++.
Anyway, I've set up a script parser to check a text file to find out
how many races there are, then dynamically alocate an array 'RaceClass
* RaceList = new RaceClass[NumRaces];'
Now, upon array creation, each member of that array also gets a
dynamically created list of twenty parent class body parts:
' BodyClass * BodyPart;
RaceClass () {
BodyPart = new BodyClass[20];
};'

Advice: use a std::vector, not a raw array.

Then the text file for each race is parsed to see how many of different
types of limbs that race has, and limbs are alocated.
Now, this works:
' if ( fieldData[1] == "Arm" ) {
NewBodyPart = new ArmClass;
CurRace.BodyPart[t] = (const BodyClass&)
*NewBodyPart;
};'
I know this because the constructer for the 'ArmClass' alocated the
right variable.

A constructor doesn't allocate the object it's called on.

You have a memory leak because you don't deallocate the allocated
ArmClass object.

It's possible you also have a type error because of your C-style cast.

Advice: avoid all casts, and C-style casts in particular. They tell the
compiler that you know what you're doing. And you don't.

Also, to have polymorphic behavior, if that's what you're at (which
seems to be the case), you need the elements of BodyPart to pointers to
BodyClass objects instead of directly being BodyClass objects.

The declaration of BodyPart should look something like this:

std::vector<BodyClass*> BodyPart;

Hth.
 
N

Narf the Mouse

Alf said:
* Narf the Mouse:
I'm currently working on a roguelike

What's a "roguelike"? I'd guess something related to a game?

as an excercise in learning c++.
Anyway, I've set up a script parser to check a text file to find out
how many races there are, then dynamically alocate an array 'RaceClass
* RaceList = new RaceClass[NumRaces];'
Now, upon array creation, each member of that array also gets a
dynamically created list of twenty parent class body parts:
' BodyClass * BodyPart;
RaceClass () {
BodyPart = new BodyClass[20];
};'

Advice: use a std::vector, not a raw array.

I just started figuring out classes; I'm not even sure what a vector
is.
Then the text file for each race is parsed to see how many of different
types of limbs that race has, and limbs are alocated.
Now, this works:
' if ( fieldData[1] == "Arm" ) {
NewBodyPart = new ArmClass;
CurRace.BodyPart[t] = (const BodyClass&)
*NewBodyPart;
};'
I know this because the constructer for the 'ArmClass' alocated the
right variable.

A constructor doesn't allocate the object it's called on.

It can, however, set variables - I use it to set an int variable so I
can later check which body part it is.
You have a memory leak because you don't deallocate the allocated
ArmClass object.

Wouldn't that delete the object now referenced by
'CurRace.BodyPart[#]'? Or am I mistaking what's happening.
It's possible you also have a type error because of your C-style cast.

Advice: avoid all casts, and C-style casts in particular. They tell the
compiler that you know what you're doing. And you don't.

Well, I knew that last bit. What kind of casts should I use?
Also, to have polymorphic behavior, if that's what you're at (which
seems to be the case), you need the elements of BodyPart to pointers to
BodyClass objects instead of directly being BodyClass objects.

Isn't that what this does?
'> > ' BodyClass * BodyPart;
RaceClass () {
BodyPart = new BodyClass[20];
};''
The declaration of BodyPart should look something like this:

std::vector<BodyClass*> BodyPart;

Hth.

Thanks for the advice. I'll look into vectors.
 
N

Narf the Mouse

Alf said:
* Narf the Mouse:

What's a "roguelike"? I'd guess something related to a game?

Whoop, missed that the first time around. Hope I'm not committing some
horrible breach of netiquette by double-posting.

My favorite roguelike is at www.adom.de
The most popular and well-known is nethack; however, I never really got
into it.

Basically, it's a text RPG where everything is represented by ASCII
symbols. Gameplay is obviously the main selling point. In a typical
roguelike, the character heads down a dungeon to kill/find foo. Beyond
that, they can get quite complex (Adom has a main map, main quest with
three different endings, side quests and side quest lines and hundreds
of monsters and items, 12 races and 20 classes).
 
D

Dave Steffen

Narf the Mouse said:
Alf said:
* Narf the Mouse: [...]
Advice: use a std::vector, not a raw array.

I just started figuring out classes; I'm not even sure what a vector
is.

Then you're not learning C++ The Right Way (TM). :)

My strong advice to you is run (don't walk) to Koenig and Moo,
"Accelerated C++".

----------------------------------------------------------------------
Dave Steffen, Ph.D. Nowlan's Theory: He who hesitates is not
Software Engineer IV only lost, but several miles from the
Numerica Corporation next freeway exit.
ph (970) 419-8343 x27
fax (970) 223-6797 The shortest distance between two points
(e-mail address removed) is under construction. -- Noelie Alito
 
A

Alf P. Steinbach

* Narf the Mouse:
' if ( fieldData[1] == "Arm" ) {
NewBodyPart = new ArmClass;
CurRace.BodyPart[t] = (const BodyClass&)
*NewBodyPart;
};'
You have a memory leak because you don't deallocate the allocated
ArmClass object.

Wouldn't that delete the object now referenced by
'CurRace.BodyPart[#]'? Or am I mistaking what's happening.

BodyPart doesn't reference anything, it _is_ an object.

You're copying an object by value, then leaving the dynamically
allocated original still allocated, taking up memory somewhere.

To store a pointer to the object instead, you need to declare BodyPart
as an array or std::vector of pointers; the latter is highly
recommended, but I guess you'll have to experience the horrors of raw
arrays first before you'll convert to The Right Faith... ;-)

 
D

Daniel T.

"Narf the Mouse said:
I'm currently working on a roguelike as an excercise in learning c++.
Anyway, I've set up a script parser to check a text file to find out
how many races there are, then dynamically alocate an array 'RaceClass
* RaceList = new RaceClass[NumRaces];'
Now, upon array creation, each member of that array also gets a
dynamically created list of twenty parent class body parts:
' BodyClass * BodyPart;
RaceClass () {
BodyPart = new BodyClass[20];
};'
Then the text file for each race is parsed to see how many of different
types of limbs that race has, and limbs are alocated.

The text file doesn't need to be parsed, according to the c_tor above,
every RaceClass has 20 BodyParts...
Now, this works:
' if ( fieldData[1] == "Arm" ) {
NewBodyPart = new ArmClass;
CurRace.BodyPart[t] = (const BodyClass&)
*NewBodyPart;
};'
I know this because the constructer for the 'ArmClass' alocated the
right variable.

You are assigning an ArmClass object to a BodyClass object, altho this
may assign the variable you are looking at, chances are it didn't really
work. After the assignment the BodyPart[t] in question is *not* an
ArmClass object. It looses all ArmClass functionality. This is called
object slicing.
This doesn't:
' if ( fieldData[1] == "Leg" ) {
NewBodyPart = new LegClass;
CurRace.BodyPart[t] = (BodyClass*) NewBodyPart;
};'
I know this because Dev cpp returns an error on it.

CurRace.BodyPart[t] is a BodyClass object, *not* a pointer to a
BodyClass object. Trying to assign a LegClass pointer to a BodyClass
object probably shouldn't work.
My guess is, it gets a pointer to NewBodyPart, then turns the pointer
into a reference for BodyClass - But I'm a newbie and would appreciate
an explanation of what I just did. Thanks.

It's the '*' before the 'NewBodyPart' that makes it work...
'NewBodyPart' is a pointer to a BodyClass object (ie it was defined as
'BodyClass *NewBodyPart' so putting the '*' in front of it means you
want to use the BodyClass *in* the pointer rather than the pointer
itself.


There are some severe logic errors in the code you have posted. As
Indigo Montoya once said, "I do not think it means what you think it
means." I recommend you find yourself a mentor/tutor.
 
N

Narf the Mouse

Narf said:
I'm currently working on a roguelike as an excercise in learning c++.
Anyway, I've set up a script parser to check a text file to find out

Thanks everybody for all your help.
 
J

Jim Langston

Narf the Mouse said:
* Narf the Mouse:
I'm currently working on a roguelike

What's a "roguelike"? I'd guess something related to a game?

as an excercise in learning c++.
Anyway, I've set up a script parser to check a text file to find out
how many races there are, then dynamically alocate an array 'RaceClass
* RaceList = new RaceClass[NumRaces];'
Now, upon array creation, each member of that array also gets a
dynamically created list of twenty parent class body parts:
' BodyClass * BodyPart;
RaceClass () {
BodyPart = new BodyClass[20];
};'

Advice: use a std::vector, not a raw array.

I just started figuring out classes; I'm not even sure what a vector
is.
Then the text file for each race is parsed to see how many of different
types of limbs that race has, and limbs are alocated.
Now, this works:
' if ( fieldData[1] == "Arm" ) {
NewBodyPart = new ArmClass;
CurRace.BodyPart[t] = (const BodyClass&)
*NewBodyPart;
};'
I know this because the constructer for the 'ArmClass' alocated the
right variable.

A constructor doesn't allocate the object it's called on.

It can, however, set variables - I use it to set an int variable so I
can later check which body part it is.
You have a memory leak because you don't deallocate the allocated
ArmClass object.

Wouldn't that delete the object now referenced by
'CurRace.BodyPart[#]'? Or am I mistaking what's happening.
It's possible you also have a type error because of your C-style cast.

Advice: avoid all casts, and C-style casts in particular. They tell the
compiler that you know what you're doing. And you don't.

Well, I knew that last bit. What kind of casts should I use?
Also, to have polymorphic behavior, if that's what you're at (which
seems to be the case), you need the elements of BodyPart to pointers to
BodyClass objects instead of directly being BodyClass objects.

Isn't that what this does?
'> > ' BodyClass * BodyPart;
RaceClass () {
BodyPart = new BodyClass[20];
};''

No. BodyPart is a pointer to BodyClass.
BodyPart = new BodyClass[20]; makes 20 instances of BodyClass and has
BodyPart point to them.

But, for polymorphic behavior, you need pointers to BodyClass.

BodyClass* BodyPart[20];
Now this is an array of 20 pointers to BodyClass. If you wanted to allocate
the memory dynamically I guess you could do:
BodyClass** BodyPart;
BodyPart = new *BodyPart[20];
or something like that (not positive that is correct syntax).

Using BodyClass* BodyPart[20]; you can now say:
if ( fieldData[1] == "Leg" ) {
NewBodyPart = new LegClass;
CurRace.BodyPart[t] = NewBodyPart;
};

if NewBodyPart is declared as LegClass or BodyClass it'll work either way,
no casted required.

Make sure you do a delete CurRace.BodyPart[t] at some point to release the
memory. You use new, you must use delete whe you're done with the memory.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top