By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,369 Members | 1,138 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,369 IT Pros & Developers. It's quick & easy.

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

P: n/a
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::operator=(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.

Jan 25 '06 #1
Share this Question
Share on Google+
8 Replies


P: n/a
* 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.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jan 25 '06 #2

P: n/a

Alf P. Steinbach wrote:
* 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.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?


Jan 25 '06 #3

P: n/a

Alf P. Steinbach wrote:
* Narf the Mouse:
I'm currently working on a roguelike


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).

Jan 25 '06 #4

P: n/a
"Narf the Mouse" <lr******@telus.net> writes:
Alf P. Steinbach wrote:
* 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
dg*******@numerica.us is under construction. -- Noelie Alito
Jan 25 '06 #5

P: n/a
* 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[i] 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... ;-)

The declaration of BodyPart should look something like this:

std::vector<BodyClass*> BodyPart;

Hth.


--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jan 25 '06 #6

P: n/a
In article <11*********************@z14g2000cwz.googlegroups. com>,
"Narf the Mouse" <lr******@telus.net> wrote:
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.
--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Jan 26 '06 #7

P: n/a

Narf the Mouse wrote:
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.

Jan 28 '06 #8

P: n/a

"Narf the Mouse" <lr******@telus.net> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com...

Alf P. Steinbach wrote:
* 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.
Jan 28 '06 #9

This discussion thread is closed

Replies have been disabled for this discussion.