friend functions and forward class declarations

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

class weapon; // this gives me an error.

class character
{
        friend void weapon::addBonus(character*);
    private:
        int level, health, magic, str; // etc...
    // more stuff, member functions
};

class item
{
    // other stuff
};

class weapon : public item
{
    protected:
        int str, dex, intel, luck, reqLv; 
        // more stuff...
    public:
        void addBonus(character* Player) 
        {
            Player->str   += str;
            Player->dex   += dex;
            Player->intel += intel;
            Player->luck  += luck;
        }
};


Code::blocks tells me " invalid use of incomplete type 'struct weapon' ".

I'm guessing it's because I have to declare the parent class item as well, but I tried, and that didn't fix anything. What do I do?

You need to reorganize your code so that the members are declared after their dependencies. Like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class character;

class weapon : public item
{
    protected:
        int str, dex, intel, luck, reqLv; 
        // more stuff...
    public:
        void addBonus(character* Player);
};

class character
{
        friend void weapon::addBonus(character*);
    private:
        int level, health, magic, str; // etc...
    // more stuff, member functions
};

weapon::addBonus(character* Player)
{
	Player->str   += str;
	Player->dex   += dex;
	Player->intel += intel;
	Player->luck  += luck;
}

class item
{
    // other stuff
};


Are you making a game?
Last edited on
Ah, thanks. Didn't think of doing that, haha.

I'm not really planning it out as a game, just writing some stuff to practice what I'm picking up from the tutorial on this site.
I should really write an article about friendship and how classes should interact.

Friendships are for when you have two or more tightly-knit classes that represent different parts of the same concept. In such situations a more in depth understanding of the internals of each others classes may be necessary, and therefore friendship might be required.

And even then -- I don't recommend accessing private members directly. Usually I create a separated interface and just label it in the comments as "private interface for XXX friend class"



Here, you have two classes which represent two entirely different concepts. So there's no need for friendship here. You are needlessly making an interdependence between character and weapon that shouldn't exist, and are (ab)using friendship to destroy the overall goal of an Object Oriented design.

(honestly, practical uses of friendship are more rare than you might think. Not that they're "rare", but they're not really all that common)


Logically -- Characters might need to be aware of a Weapon, because they'll need to wield and use a weapon. So weapon is good to have as a dependency of character. However friendship is not required since they don't need an interdependent relationship, and any information character needs should be available through some kind of public interface in weapon.

In the same vein... Weapons do not need to know about characters. The only way this might make sense would be if the weapon changed its properties or behaved differently if it was being wielded by a specific character or something (and even that could be accomplished cleanly without friendship).

And if they don't need to know, they shouldn't know. 'weapon' should remain totally ignorant of 'character'.


OOP is a weird thing to wrap your head around.
Thank you for the lengthy post, disch :) I'm self teaching and OOP is confusing me a bit, heh.

So, since the character should be aware of the weapon (i.e whatever benefits it may give them), how would I go about having the weapon having an effect on the character? I mean, I think I understand what you mean, but I'm not really sure how to achieve that with code. How do I make a weapon a dependency of character without making it a friend? I'm sure you don't mean to have it inherit from character.

From what I understand, declaring a member function of weapon to be a friend of character doesn't give character access to weapon's properties, so weapon cannot be affected by character. Only that member function gains access to a character's properties, so that a weapon can add a bonus to a character's capabilities.

I was trying to keep the classes separate at first but when it came to having an object in one modify the (private/protected) properties of an object in another, I was stumped...
For character knowing about weapon, that should easily be accessible through a public interface (like get/set functions etc.)

If you wanted a weapon to be able to give an effect, you could make a constant "effect" inside the weapon that the player could access if it needs it.
Topic archived. No new replies allowed.