Connecting Tech Pros Worldwide Help | Site Map

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

  #1  
Old January 25th, 2006, 08:28 PM
Narf the Mouse
Guest
 
Posts: 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.

  #2  
Old January 25th, 2006, 08:45 PM
Alf P. Steinbach
Guest
 
Posts: n/a

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


* Narf the Mouse:[color=blue]
> I'm currently working on a roguelike[/color]

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

[color=blue]
> 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];
> };'[/color]

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

[color=blue]
> 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.[/color]

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?
  #3  
Old January 25th, 2006, 09:55 PM
Narf the Mouse
Guest
 
Posts: n/a

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



Alf P. Steinbach wrote:
[color=blue]
> * Narf the Mouse:[color=green]
> > I'm currently working on a roguelike[/color]
>
> What's a "roguelike"? I'd guess something related to a game?
>
>[color=green]
> > 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];
> > };'[/color]
>
> Advice: use a std::vector, not a raw array.[/color]

I just started figuring out classes; I'm not even sure what a vector
is.
[color=blue][color=green]
> > 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.[/color]
>
> A constructor doesn't allocate the object it's called on.[/color]

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

Wouldn't that delete the object now referenced by
'CurRace.BodyPart[#]'? Or am I mistaking what's happening.
[color=blue]
> 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.[/color]

Well, I knew that last bit. What kind of casts should I use?
[color=blue]
> 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.[/color]

Isn't that what this does?
'> > ' BodyClass * BodyPart;[color=blue][color=green]
> > RaceClass () {
> > BodyPart = new BodyClass[20];
> > };''[/color][/color]
[color=blue]
> The declaration of BodyPart should look something like this:
>
> std::vector<BodyClass*> BodyPart;
>
> Hth.[/color]

Thanks for the advice. I'll look into vectors.
[color=blue]
> --
> 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?[/color]

  #4  
Old January 25th, 2006, 10:05 PM
Narf the Mouse
Guest
 
Posts: n/a

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



Alf P. Steinbach wrote:
[color=blue]
> * Narf the Mouse:[color=green]
> > I'm currently working on a roguelike[/color]
>
> What's a "roguelike"? I'd guess something related to a game?
>[/color]

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

  #5  
Old January 25th, 2006, 10:45 PM
Dave Steffen
Guest
 
Posts: n/a

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


"Narf the Mouse" <lrgmouse@telus.net> writes:
[color=blue]
> Alf P. Steinbach wrote:
>[color=green]
> > * Narf the Mouse:[/color][/color]
[...][color=blue][color=green]
> > Advice: use a std::vector, not a raw array.[/color]
>
> I just started figuring out classes; I'm not even sure what a vector
> is.[/color]

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
dgsteffen@numerica.us is under construction. -- Noelie Alito
  #6  
Old January 25th, 2006, 10:55 PM
Alf P. Steinbach
Guest
 
Posts: n/a

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


* Narf the Mouse:[color=blue][color=green][color=darkred]
> > > ' if ( fieldData[1] == "Arm" ) {
> > > NewBodyPart = new ArmClass;
> > > CurRace.BodyPart[t] = (const BodyClass&)
> > > *NewBodyPart;
> > > };'[/color][/color]
>[color=green]
> > You have a memory leak because you don't deallocate the allocated
> > ArmClass object.[/color]
>
> Wouldn't that delete the object now referenced by
> 'CurRace.BodyPart[#]'? Or am I mistaking what's happening.[/color]

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

[color=blue][color=green]
> > The declaration of BodyPart should look something like this:
> >
> > std::vector<BodyClass*> BodyPart;
> >
> > Hth.[/color][/color]

--
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?
  #7  
Old January 26th, 2006, 04:05 AM
Daniel T.
Guest
 
Posts: n/a

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


In article <1138219854.174926.47440@z14g2000cwz.googlegroups. com>,
"Narf the Mouse" <lrgmouse@telus.net> wrote:
[color=blue]
> 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.[/color]

The text file doesn't need to be parsed, according to the c_tor above,
every RaceClass has 20 BodyParts...
[color=blue]
> 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.[/color]

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.
[color=blue]
> 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.[/color]

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.
[color=blue]
> 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.[/color]

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.
  #8  
Old January 28th, 2006, 07:15 AM
Narf the Mouse
Guest
 
Posts: n/a

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



Narf the Mouse wrote:
[color=blue]
> 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[/color]

Thanks everybody for all your help.

  #9  
Old January 28th, 2006, 07:35 AM
Jim Langston
Guest
 
Posts: n/a

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



"Narf the Mouse" <lrgmouse@telus.net> wrote in message
news:1138225334.756621.185820@g47g2000cwa.googlegr oups.com...[color=blue]
>
> Alf P. Steinbach wrote:
>[color=green]
>> * Narf the Mouse:[color=darkred]
>> > I'm currently working on a roguelike[/color]
>>
>> What's a "roguelike"? I'd guess something related to a game?
>>
>>[color=darkred]
>> > 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];
>> > };'[/color]
>>
>> Advice: use a std::vector, not a raw array.[/color]
>
> I just started figuring out classes; I'm not even sure what a vector
> is.
>[color=green][color=darkred]
>> > 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.[/color]
>>
>> A constructor doesn't allocate the object it's called on.[/color]
>
> It can, however, set variables - I use it to set an int variable so I
> can later check which body part it is.
>[color=green]
>> You have a memory leak because you don't deallocate the allocated
>> ArmClass object.[/color]
>
> Wouldn't that delete the object now referenced by
> 'CurRace.BodyPart[#]'? Or am I mistaking what's happening.
>[color=green]
>> 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.[/color]
>
> Well, I knew that last bit. What kind of casts should I use?
>[color=green]
>> 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.[/color]
>
> Isn't that what this does?
> '> > ' BodyClass * BodyPart;[color=green][color=darkred]
>> > RaceClass () {
>> > BodyPart = new BodyClass[20];
>> > };''[/color][/color][/color]

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.


Closed Thread


Similar Threads
Thread Thread Starter Forum Replies Last Post
Can any one help me find out what was the problem in this small xiao answers 9 July 21st, 2008 04:25 AM
Python's "only one way to do it" philosophy isn't good? WaterWalk answers 206 July 9th, 2007 02:25 PM
Strange Event Behaviour ChrisM answers 7 June 27th, 2006 04:15 PM
How to best parse a CSV data file and do a lookup in C? Johnny Google answers 19 November 14th, 2005 04:11 PM