Jump to content
  • Advertisement
Sign in to follow this  
password

Problem with a friend

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

If you intended to correct an error in the post then please contact us.

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 load();
    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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by TheTroll
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.


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 this post


Link to post
Share on other sites
Quote:
Original post by ToohrVyk
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() ?


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


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 this post


Link to post
Share on other sites
Quote:
Original post by password
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.


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 this post


Link to post
Share on other sites
Quote:
Original post by ToohrVyk
Quote:
Original post by password
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.


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 this post


Link to post
Share on other sites
Quote:
Original post by password
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.


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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!