class Character
{
public:
Character();//constructor
~Character();//destructor
...
...
...//some other members/member functions
Attack attackone;//character''s first attack
...
...
int strength;//The character''s strength
}//class Character
class Attack
{
public:
Attack();//constructor
~Attack();//destructor
...
...
...//insert crap here
void perform();//Perform the attack
}//class Attack
For the sake of the question, we''ll say that Attack::perform() is dependant on its character''s strength. It needs to somehow use the value of "strength" from the character object that it exists in to determine the damage that will be inflicted. I have no idea how much sense the previous sentence makes.
Anyway, how would I go about doing this?
OOP quesiton
I''m not sure if I''m quite approaching this question correctly, but here goes:
Let''s say I''m working on a fighter. I have a character class, and an attack class.
Post this in the DP forum, and I''ll try to respond tomorrow (ZZZZZZZZzzzzzzzzzzzz................)
Magmai Kai Holmlor
- The disgruntled & disillusioned
Magmai Kai Holmlor
- The disgruntled & disillusioned
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
There are a couple of ways to do this.
I am sure that there are a bunch more but those are just a couple off the top of my head.
-------
Andrew
Edited by - acraig on March 15, 2001 12:22:39 PM
- The simplest way would be to pass the strength to the Attack::perform() . ie Attack::perform(int strength)
- If the strength is constant then construct the attack with a strength value.
- Before the attack set the strength ( sorta like #1 )
I am sure that there are a bunch more but those are just a couple off the top of my head.
-------
Andrew
Edited by - acraig on March 15, 2001 12:22:39 PM
You could pass a reference to the character in the call to Attack:
erform().
class Character{
public:
Character(); //constructor
~Character();//destructor
...
...
... //some other members / member functions
Attack attackone; //character''s first attack
...
...
int strength; //The character''s strength
}//class Character
class Attack
{
public:
Attack();//constructor
~Attack();//destructor
...
...
...//insert crap here
void perform(Character &character);//Perform the attack
}//class Attack
void Attack::perform(Character &character)
{
//perform character.attackone
character.strength = 100; //or whatever you wanna do with
//the character''s strength.
}
![](tongue.gif)
class Character{
public:
Character(); //constructor
~Character();//destructor
...
...
... //some other members / member functions
Attack attackone; //character''s first attack
...
...
int strength; //The character''s strength
}//class Character
class Attack
{
public:
Attack();//constructor
~Attack();//destructor
...
...
...//insert crap here
void perform(Character &character);//Perform the attack
}//class Attack
void Attack::perform(Character &character)
{
//perform character.attackone
character.strength = 100; //or whatever you wanna do with
//the character''s strength.
}
John Licatogamecreationlab.com
OK, I typed out a really long response to this yesterday, but the forum was screwed and ate my post. I''ll give it another shot here.
One solution (not saying the best) is to have the attack know its parent character. I''ll show the code, then show how to implement it:
OK, so there''s lots going on here. You''re creating a circular dependency between the two classes, which isn''t always a good thing, but might work for you.
You''re using an object of type Attack "in size" in the Character class. "In size" means you''re using an object, not a reference or pointer, so by the time the compiler gets to Character, it needs to know the exact size of Attack so it can incorporate it into the size of Character. This means that the Attack class _must_ be declared before the Character class.
However, the Attack class uses the Character class in its interface; since it''s just using a reference, you can get away with a forward declaration of Character (i.e. "class Character;") just before the declaration of Attack.
Attack has an internal reference to a character. Since this is a reference, its value must be set in the member initialization list of the Attack constructor. If you wanted to initialize it at some other time, you could change the reference to a pointer and do so.
Character, likewise, contains an Attack "in size"; since all constructors of members of a class are called before the class constructor is called, you must also initialize attackone in the member initialization list. Simple pass the dereferenced "this" pointer to attackone, and attackone''s constructor will store it as its m_rCharacter.
From now on, you''re free to use any of the public members of the Character object from within the Attack class. An example of how to do this is shown in Attack::perform ().
There are other ways to do this as other posters have shown. One is to pass the strength as a parameter, another is to pass a reference to Character each time. I prefer something like this method, but it does have the consequence of creating a circular dependency. Given more time, I believe I could construct a method that does not create that dependency, but I think it would require a third class (i.e. an "AttackManager").
So many ways to skin an OO cat.
(Hope the forum saves my reply this time)
One solution (not saying the best) is to have the attack know its parent character. I''ll show the code, then show how to implement it:
|
OK, so there''s lots going on here. You''re creating a circular dependency between the two classes, which isn''t always a good thing, but might work for you.
You''re using an object of type Attack "in size" in the Character class. "In size" means you''re using an object, not a reference or pointer, so by the time the compiler gets to Character, it needs to know the exact size of Attack so it can incorporate it into the size of Character. This means that the Attack class _must_ be declared before the Character class.
However, the Attack class uses the Character class in its interface; since it''s just using a reference, you can get away with a forward declaration of Character (i.e. "class Character;") just before the declaration of Attack.
Attack has an internal reference to a character. Since this is a reference, its value must be set in the member initialization list of the Attack constructor. If you wanted to initialize it at some other time, you could change the reference to a pointer and do so.
Character, likewise, contains an Attack "in size"; since all constructors of members of a class are called before the class constructor is called, you must also initialize attackone in the member initialization list. Simple pass the dereferenced "this" pointer to attackone, and attackone''s constructor will store it as its m_rCharacter.
From now on, you''re free to use any of the public members of the Character object from within the Attack class. An example of how to do this is shown in Attack::perform ().
There are other ways to do this as other posters have shown. One is to pass the strength as a parameter, another is to pass a reference to Character each time. I prefer something like this method, but it does have the consequence of creating a circular dependency. Given more time, I believe I could construct a method that does not create that dependency, but I think it would require a third class (i.e. an "AttackManager").
So many ways to skin an OO cat.
(Hope the forum saves my reply this time)
AACCCCCCCCCHHHHHHHHHHhhhhh!!!!!!!!
OOP, keep it away! keep it away!!!
*arsenius runs behind a chair*
-arsenius
''after three days without programming, life becomes meaningless'' -The Tao of Programming
OOP, keep it away! keep it away!!!
*arsenius runs behind a chair*
-arsenius
''after three days without programming, life becomes meaningless'' -The Tao of Programming
quote:
Original post by arsenius
AACCCCCCCCCHHHHHHHHHHhhhhh!!!!!!!!
OOP, keep it away! keep it away!!!
*arsenius runs behind a chair*
-arsenius
''after three days without programming, life becomes meaningless'' -The Tao of Programming
Your Tao of Programming has just enlightened me. Therefore, I will not have to test my programs anymore, because they''re perfect in themselves now.
![](smile.gif)
But before you can realize Tao, you have to process the Evolution of a programmer!
http://www.ariel.com.au/jokes/The_Evolution_of_a_Programmer.html
![](wink.gif)
(Computer && !M$ == Fish && !Bike)
I would tend to recomment the first suggestion of passing a reference to your strength variable to Perform (ie, Attack::perform(int &strength)
.
The reason I choose this over circular dependancy is because I''d rather keep my classes as ignorant of each other as possible. The more classes are dependant on other classes, the less reusable your class is.
- Houdini
![](wink.gif)
The reason I choose this over circular dependancy is because I''d rather keep my classes as ignorant of each other as possible. The more classes are dependant on other classes, the less reusable your class is.
- Houdini
- Houdini
quote:
Original post by Houdini
I would tend to recomment the first suggestion of passing a reference to your strength variable to Perform (ie, Attack::perform(int &strength).
The reason I choose this over circular dependancy is because I''d rather keep my classes as ignorant of each other as possible. The more classes are dependant on other classes, the less reusable your class is.
I agree with the reusability. But why would you want to pass a reference to an integer? Is Perform allowed to change strength? It seemed from the original post that it should not. Strength should be passed as an int, not as an int &.
quote:
Original post by Stoffel
I agree with the reusability. But why would you want to pass a reference to an integer? Is Perform allowed to change strength? It seemed from the original post that it should not. Strength should be passed as an int, not as an int &.
It''s generally better to pass parameters by reference rather than value. The reasoning is that if you pass a large class to a function the function actually creates a seperate instance of the class and copies every variable from the original class into the new class. If you pass by reference then you are just passing a 4 byte memory address pointing to the original class, and no creating/copying of classes are involved.
Of course, passing an integer and passing a reference to an integer both passes 4 bytes, so in this case it TRUELY doesn''t matter. However, I always pass by reference both out of habit and to keep things uniform.
BTW, you are correct that the perform function I posted allowed the strength variable to be modified. It should have included a const:
Attack::perform(const int &strength);
- Houdini
- Houdini
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement