I was reading an old C++ book to do some retro coding, C++ for C Programmers by Sharam Hekmatpour, I remember reading it when I was way younger and I liked it.
In the friend functions chapter he shows having two classes with friend functions:
class RealSet;
class IntSet {
public:
void ToRealSet(RealSet*);
friend void RealSet::ToIntSet(IntSet*);
};
class RealSet {
public:
void ToIntSet(IntSet*);
friend void IntSet::ToRealSet(RealSet*);
};
I know this won't compile because while we had defined RealSet as a forward declaration, we don't have a definition to RealSet::ToIntSet and that will make the compiler fail.
Yes, I know I could set the whole class as a friend class and that will solve the problem:
class RealSet;
class IntSet {
public:
ToRealSet(RealSet*);
friend class RealSet;
};
class RealSet {
public:
ToIntSet(IntSet*);
friend class IntSet;
};
My question is simple: Was this ever possible or is it a typical book mistake?
Related
Is it possible to create a class that has a friend function of a forward declared class? If I wanted to create two classes that have friend functions of each other, how would I do that? This attempt fails with the message invalid use of incomplete type 'class Y':
class Y;
class X
{
public:
void a();
friend void Y::b();
};
class Y
{
public:
void b();
friend void X::a();
};
I also tried forward declaring void Y::b(); right after class Y; which similarly did not work. Would this example be an indicator of bad design on my part or just a limitation of C++?
This question already has answers here:
Specify a class member function as a friend of another class?
(8 answers)
Closed 3 years ago.
I'm taking a C++ course, and I came across something I can't wrap my head around. I've tried searching for an answer, but I've come up short.
class A {
friend void C::dec(A&);
private:
int field;
};
class C {
public:
void dec(A& a);
};
void C::dec(A& a) { a.field--; } <-- member A::field is inaccessible
I am aware that for this to work, class A should be declared before, but defined after, class C. But I'm struggling to understand why.
So why is the class member A::field inaccessible when class A is defined before class C?
The problem is not the friend declaration, it's just C is unknown where you declare it in A.
So you define C and forward declare A, then just define C as you already did.
class A;
class C {
public:
void dec(A& a);
};
class A {
friend void C::dec(A&);
private:
int field;
};
void C::dec(A& a) { a.field--; }
I'm having two classes, PlayerCharacter and Ability. The Ability class has an pure virtual function which I declare as a friend to PlayerCharacter. However, I seem to be unable to access the private members within the friend declared function. Is it something I overlook?
I have attemped to declare the child function rather than the virtual one as the friend function, but to no effect.
player_chracter.h :
#include "ability.h"
class PlayerCharacter : public Character {
private:
// Friend function
friend bool Ability::ExecuteAbility(PlayerCharacter& in_player);
// This doesn't work either
//friend bool Dash::ExecuteAbility(PlayerCharacter& in_player);
// Private variable
float top_speed_;
}
ability.h :
//Forward declaration
class PlayerCharacter;
class Ability {
public:
Ability();
~Ability();
virtual bool ExecuteAbility(PlayerCharacter& in_player) = 0;
};
//---------------------------------------------------------
class Dash : public Ability {
public:
Dash();
~Dash();
bool ExecuteAbility(PlayerCharacter& in_player);
};
ability.cpp :
#include "ability.h"
#include "player_character.h" //Follow through on forward declaraction
bool Dash::ExecuteAbility(PlayerCharacter& in_player) {
float example = in_player.top_speed_;
}
In the code above, why cannot I access top_speed_ and put it in the float example variable?
As per [class.friend]/10, friendship is not inherited.
A derived class does not automatically become a friend of a class just because its parent class is a friend of that class.
The reason why the below also does not work either is probably because Dash is not defined before the function ExecuteAbility is defined.
friend bool Dash::ExecuteAbility(PlayerCharacter& in_player);
However, with the proper order of definitions it will work. See DEMO.
From cppreference:
Friendship is not transitive (a friend of your friend is not your friend)
Friendship is not inherited (your friend's children are not your friends)
Even if Dash::ExecuteAbility overrides a friend function from its base class, it does not benefit from it. You'll have to rethink your design.
I have just started learning friend functions in C++.This is the program which I am using for the concept exploration.
#include<iostream>
using namespace std;
class one
{
private:
int age;
public:
one()
{
age=1;
}
void setData(int num)
{
age=num;
}
friend int returnOne(one a);
};
int returnOne(one a)
{
return a.age;
}
class two
{
private:
int roll;
public:
two()
{
roll=0;
}
void setData(int num)
{
roll=num;
}
friend int returnTwo(two b);
};
int returnTwo(two b)
{
return b.roll;
}
int main()
{
one a;
two b;
a.setData(10);
b.setData(12);
cout<<returnOne(a)<<endl<<returnTwo(b)<<endl;
}
Now I am worried that the security of class one and two has been compromised as now anyone can use those globally defined friend functions to access class one's and class two's private members.
How can I provide protection to these friend functions or restrict their usage?
friend ship is mutual. Unless one declares the function as friend in the class definition a function cannot be friended, so it's a choice. If you make it you have to live with it. It makes no sense to make a function friend and then try to prevent it from accessing the class internals because that is exactly the purpose of keyword friend.
Do not misuse or misinterpret friendship.
friendship is used to indicate a intentional strong coupling between two entities. If there exists a special relationship between two entities such that one needs access to others private or protected members but You do not want everyone to have access by using the public access specifier then you should use friendship.
Declaring a friend function in a class extends the classes public interface. You are basically extending the class with more functions (at the cost of tightly coupling those functions).
So you can not stop people using those functions just like you can not stop people using public member methods on your class (they are all part of the public interface).
But you could re-design your friend functions so they do not expose implementation details.
Why not define operator<< for your class instead of a functions that access particular members (this is assuming you are providing these functions simply for streaming (if not then the point is mute)).
std::ostream& operator<<(std::ostream& s,two const& b)
{
return s << b.roll;
}
When defining a class as a friend class, does it matter in which accessor section the definitions is placed, and if so does that change the members the friend has access to?
class aclass
{
private:
// friend bclass;
public:
// friend bclass;
protected:
// friend bclass;
};
class bclass
{};
Access specifiers do not apply to friend function/Class
You can declare the Friend Function or Class under any Access Specifier and the Function/Class will still have access to all the member variables(Public,Protected & Private) of that Class.
Once you place friend class/function inside a given class (say 'aclass') anywhere. It will have access to all defined members of the class (irrespective of public/private/protected); for example:
class aClass
{
public: int pub; void fun1() {}
protected: int pro; void fun2() {}
private: int pri; aClass(const aClass& o);
friend void outsider ();
};
Friend function outsider() can access pub, pro, pri, fun1, fun2; but not aClass copy constructor in this case (if it's not defined anywhere).
Friend functions aren't placed inside any accessors by convention, because by definition they aren't part of the class. You might do something like this:
class Elephants
{
//friend void notAMemberFuncion(argument 123);
public:
// member functions;
protected:
// data members;
};
The friend class/function can access all the private/protected/public members of class, which access section the friend class/function is placed doesn't make any difference.
It's suggested to put friend class/function in the public section, because friends is part of the class interface.