Jump to content
  • Advertisement
Sign in to follow this  
Darkbouncer4689

C++ friend

This topic is 2590 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

Trying to solidify the concept of the friend keyword in C++.

Seems like there are a few ways to use it.

class Cat
{
friend class Dog;
private:
int age;
};

If the class Dog contains an instance of class Cat it can now access Cat's protected/private data without needing public accessor methods.

If instead it were something like

friend void Dog::DoSomething()

Then only in the method DoSomething would Dog be able to access Cat's protected/private data.

And last if it was something like

class Cat
{
friend void PrintAge(Cat& cat) {cout << cat.age << endl;}
private:
int age;
};

This method is like a static method that can be called without an instance of the class and can access the instances private data. I'm not noticing a difference here between a static and friend function other than the friend function is global and the static version needs a full declaration such as Cat::StaticFunction(). Could anyone explain?


Thanks!

Share this post


Link to post
Share on other sites
Advertisement

class Cat {
friend void PrintAge(Cat& cat) {cout << cat.age << endl;}
private:
int age;
};


Someone correct me if I'm wrong, but friend seems redundant and useless for a member function. Also, the method is not static because it has not been declared as such. You still need a Cat object to call it from, even though it works on a different Cat object.

Share this post


Link to post
Share on other sites
Interesting, so the following won't work

class Cat
{
friend void Hello() {cout << "Hello" << endl;}
};

int main()
{
Hello();
}


but this does work

class Cat
{
friend void Hello(Cat& cat) {cout << "Hello" << endl;}
};

int main()
{
Cat cat;
Hello(cat);
}

So it somehow uses the parameter passed in to call the method?

Share this post


Link to post
Share on other sites
I most commonly use friend for a C callback. ie

[source lang="cpp"]
class Cat
{
private:
friend int ApiCallback(void *);
void OnCallback();
};
[/source]

thus, my ApiCallback can do stuff with Cat
[source lang="cpp"]
int ApiCallback(void *userPtr)
{
((Cat*)userPtr)->OnCallback();
}
[/source]

In your example, your friend declaration has created an in-place, (inline?) function, which is *not* a member of the class but *has* inherited the privacy of the class at that stage. In the first example, you can demonstrate this with the following code:

[source lang="cpp"]
class Cat
{
friend void Hello() {cout << "Hello" << endl;} //implicitly private
public:
static void CallHello() { Hello(); }
};

int main()
{
Cat::CallHello(); //this works
Cat::Hello(); //this doesn't
Hello(); //nor does this
}
[/source]

My guess is that your second example ( [color="#1C2837"]Hello(Cat& cat) ) works because it references the class, so the compiler defers compilation of the inline function until after the class declaration has completed, causing it to then correctly identify it as not subject to the class privacy constraint.

So in short, it seems non-standard and so probably compiler specific in how it works (I tested on VS2010, which compiler are you using? Maybe it works differently with gcc?)

Share this post


Link to post
Share on other sites


class Cat {
friend void PrintAge(Cat& cat) {cout << cat.age << endl;}
private:
int age;
};


Someone correct me if I'm wrong, but friend seems redundant and useless for a member function. Also, the method is not static because it has not been declared as such. You still need a Cat object to call it from, even though it works on a different Cat object.
Okay, well FYI you're wrong.

friend has about the same effect as static here, the difference being that it allows the method to be placed inside the class body. Just like when using static, an instance is not required to call the method on, although typically one would make one of the parameters to that method be an instance of that class, as shown above.

Share this post


Link to post
Share on other sites
Okay so in this case friend and static are very similar. I think friend is a bit cleaner since it doesnt require scope resolution operator each time. (Although some may be against it since it could be confusing as to where that method is defined)

Thanks guys!

P.S. I'm thinking the cleanest use for this is to override the ostream/istream operators.

friend ostream& operator<<(ostream&, Cat&);








[font="Consolas"] [/font]

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!