Public Group

# Problem with a friend

This topic is 4406 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi! My name is Level and I have this friend called Player::tilecollision() and we don't really get along with each other that well. Even if we're friends, Player::tilecollision() won't access/use any of my belongings, in this case an array called level. My class currently looks like this.
class Level {
public:
Level() { }

void draw();

friend bool Player::tilecollision();
void ChangeLevel(int n);

Tile level[LEVELWIDTH][LEVELHEIGHT];
};


And I want Player::tilecollision() to be able to access my level array. The problem is that he can't access it even if we're friends. Am I doing something wrong? player.cpp `level' undeclared (first use this function) Player::tilecollision() is definied like this in its class. bool Player::tilecollision() { // code }

##### Share on other sites
Level is a class, it has no belongings. Instances of Level do have the belongings which are described in Level. Therefore, the question becomes: which instance of the class Level are you accessing in Player::tilecollision() ?

##### Share on other sites
Also, how are you trying to access level? From the error message, it almost sounds as though you are trying to use it exactly the same as if it was a property of Player itself, whereas (as ToohrVyk said) it needs to be accessed as a property of a specific instance of Level (e.g. Game::GetCurrentLevel()->level, rather than just level)

##### Share on other sites
From what I have seen, the best solution to a "freinds" problem is don't use friends. Most people use friends completely wrong and break the encapsilation of the classes. Make proper accessors to your class you want to access and go that way. Many less headaches in the future.

theTroll

##### Share on other sites
Quote:
 Original post by TheTrollFrom what I have seen, the best solution to a "freinds" problem is don't use friends. Most people use friends completely wrong and break the encapsilation of the classes. Make proper accessors to your class you want to access and go that way. Many less headaches in the future.

Actually, accessors often cause the same problems (because they access the object data, even if through a layer of checks), and it seems quite probable to me that someone who would misuse friend would also misuse accessors.

A good way to enforce encapsulation is to design and use the interface before implementing it. Write code that uses the object until you're fairly certain that it's elegant and comfortable to use. Don't access data members, only methods, unless you're going for a storage-only all-public object (such as structs in C). Then, determine what the signature (its public methods) will look like, and implement everything with no-ops. Then, write unit testing code, make sure that it fails on the mock, no-op object, and start implementing the signatures to correspond with the unit tests.

In the end, you have an object in which encapsulation was introduced before the very start, and its usage was not thought in terms of its implementation at all.

##### Share on other sites
Quote:
 Original post by ToohrVykLevel is a class, it has no belongings. Instances of Level do have the belongings which are described in Level. Therefore, the question becomes: which instance of the class Level are you accessing in Player::tilecollision() ?

My intention is not to access an instance of Level but to make the tilecollision function be able to use the members of the Level class.

Quote:
 Original post by AndyGeersAlso, how are you trying to access level? From the error message, it almost sounds as though you are trying to use it exactly the same as if it was a property of Player itself, whereas (as ToohrVyk said) it needs to be accessed as a property of a specific instance of Level (e.g. Game::GetCurrentLevel()->level, rather than just level)

I see I referred it to "level[x][y]". Shouldn't it work if I just refer to level as "Level::level[5][5]" instead of "level[5][5]" in the tilecollision() function then? Making an instance to access the level class sounds really strange, then I could use references, pointers, global level instance etc instead. I'm sure i've used a friends before without the need to make an instance.

##### Share on other sites
Quote:
 Original post by passwordMy intention is not to access an instance of Level but to make the tilecollision function be able to use the members of the Level class.

Your class has no members. A class describes the members of its instances. In particular, Level::level does not exist. l.level does, where l is an instance of level. If this is not clear to you, I suggest that you go back to your C++ book and read the chapter on classes again until this becomes clear. Without this fundamental knowledge, you will not be able to use classes correctly.

An alternative is to use static members, which are shared across all instances and are accessible globally. This would prevent you from having different data for different levels (since all levels would share the same data), and in your case serves strictly no purpose at all over plain global variables. In any case, your program is guilty of Very Bad DesignTM. If you wish to keep your design, at least stop hiding behind the "it's a class" reassuring argument, and use global variables.

Quote:
 I'm sure i've used a friends before without the need to make an instance.

Friendship and instantiation are orthogonal concepts. Friendship determines who may access a given field, while instantiation determines whose fields may be accessed.

##### Share on other sites
Quote:
Original post by ToohrVyk
Quote:
 Original post by passwordMy intention is not to access an instance of Level but to make the tilecollision function be able to use the members of the Level class.

Your class has no members. A class describes the members of its instances. In particular, Level::level does not exist. l.level does, where l is an instance of level. If this is not clear to you, I suggest that you go back to your C++ book and read the chapter on classes again until this becomes clear. Without this fundamental knowledge, you will not be able to use classes correctly.

I already know that, you most have misunderstood what I meant. It's just that I don't see the purpose of using friends at all when you can just send the instance as a parameter from the beginning. It sounds totally useless to use friends if that's the case. I was pretty sure that friends were like a derived class (not 100% but the idea), it have access to the base class's members like it belongs to the class itself.

I will just do this in another way and forget this friend issue.

##### Share on other sites
Quote:
 Original post by passwordI already know that, you most have misunderstood what I meant. It's just that I don't see the purpose of using friends at all when you can just send the instance as a parameter from the beginning. It sounds totally useless to use friends if that's the case. I was pretty sure that friends were like a derived class (not 100% but the idea), it have access to the base class's members like it belongs to the class itself.

Consider it this way: friendship, private, public and protected are the key, an instance is the door, and the member is behind the door. If you have an instance, but don't have public or friend access to its members, you have a door but can't open it. If you're the friend of a class, but have no instance of that class, then you have a key but no door to open. You can only access a member when you have both an instance and the right to access that member for that instance.

An example where friend is useful: writing an operator<<(ostream&,const theclass&), which would need to access the members of the class instance even though they are private.

1. 1
2. 2
3. 3
Rutin
14
4. 4
5. 5

• 9
• 9
• 11
• 11
• 23
• ### Forum Statistics

• Total Topics
633674
• Total Posts
3013276
×