[OOP] Two classes that can acces each other's members

Started by
15 comments, last by Mussi 11 years, 8 months ago
Hello.
Suppose I have two classes : class A and class B .
In my program , A needs to acces some of B's members but B also has to acces some of A's members.
If it's possible, how do I implement this in C++ ?
A and B are separate entities.I do not want to include one of them as a member of the other one .
Advertisement
A. Make all members public
B. Expose a public interface to those members on either class
C. Declare A and B as mutual friend classes.
D. Rethink your design
Could you tell us more about what you're trying to implement?
@Mussi Well the A and B are the player and the enemy.
The enemy's AI is implemented as a state machine. By default , he leaves the player alone.
The player can however trigger the "Attack" stance of the enemy, but for that he needs to read some info from the enemy object(the enemy position for example).
In order to run the "Attack" stance, my enemy also has to read the player object's informations (like player position and speed for example);
Also, he must modify the player's speed at begining of the "Attack" stance and set it back after the "Attack" finishes.
I've adopted this method because it seems more logical to me. Only the enemy knows when he stops the attack and its reasonable that he reinitializes the player's speed too.There's no point in querying the player object
" Are you in a "chased" stance ? " at each iteration, at least I dont think so.

@Madhed
C.How do I do that ?
From what I know , if A is a friend of class B, then there must be an object of type B in A's declaration so that A can acces the private B's stuff.

I used to classes just for this example.In reality , the player must acces the members of a second class too, C containing the obstacles .
I think what you're looking for is forward declaration and friendship. Here's the best I can do without any more information:
[source lang="cpp"]class A;

class B{
friend class A;
int x; // can be any data type, I chose int for simplicity
public:
void do_stuff(A a_object); // some function that acts on an A's private members
};

class A{
friend class B;
int y;
public:
void do_stuff(B b_object);
};[/source]
Now you can do something like:
[source lang="cpp"]B::do_stuff(A a_object)
{
a_object.x += 1;
}

A::do_stuff(B b_object)
{
b_object.y += 1;
}[/source]
A few alternatives to consider: only feed the information that's necessary instead of the entire object and/or introduce a third class/function that takes both objects and passes on information to each other.
"Player" and "Enemy" don't sound like distinct classes to me - they are "combatant"

"Combatant" has speed, position, possibly weapons, inventory, etc..

Then "Player" is a class derived from "Combatant" - uses input (keyboard,mouse, etc.) to change animations, positions, etc.

And "Enemy" is also class derived from "Combatant" - but this uses AI to drive it...

This would also allow later for AI characters to fight on either side, or possibly have multiple factions...
And networked / LAN players could be derived as well...
Oops.. forgot the last bit as well...

So - if any combatant needs info on another combatant, it just accesses the base-class ( or higher class through an interface / virtual function )..

No combatant knows or cares what is "brains" - only if they are "friend" or "foe" or if they're attacking, etc.. etc..
I should have posted a more detailed reply. Actually you should first consider points B or D from my list. Using friend declarations is almost always a bad code smell and you should consider doing it differently.

Why don't you introduce another layer as Mussi has suggested. A system that keeps track of object positions, where the Enemies can create triggers that get executed when a player enters. That way the logic is a level higher than the individual players or enemies and the enemies just get notified when a player enters their field of view.
I have to agree with Madhed here. If you end up having a circular reference between two distinct classes, it usually implies your code design has failed, and there is often a better solution to achieve what you are after.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”

This topic is closed to new replies.

Advertisement