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.
Related
I would like to combine the concepts of polymorphism and friendship. I am making a pure virtual member function of a base class a friend of another class. I would then like to override this pure virtual member function in the classes derived from that base class, and access private member data of the class who has such function as friend. See the code snippet below. The compiler complains when I refer to my_int in the derived classes member function add(). I understand friendship is a 1-to-1 relationship, but I wonder if there is any way around it so as to implement polymorphism. Do I just have to make the member functions of the different derived classes friends of the foo() class?
class foo {
private:
int my_int{};
public:
friend virtual int base::add();
};
class base {
public:
virtual int add() = 0;
};
class derived_1 : public base {
public:
int add() {
return my_int + 1;
}
};
class derived_2 : public base {
public:
int add() {
return my_int + 2;
}
}
First, with what you've displayed it's not going to work because my_int is a member of foo but in the base class tree there is no 'foo' to get the member from.
The easy answer would be to make the function take an int argument and do away with the use of friend entirely.
struct derived2 : base
{
int add(int arg) { return arg + 2; }
};
The use of 'friend' should make you seriously question whether what you are doing is a good answer, sometimes the answer to that question is 'yes' but not often. And the more friends you need the less often the answer remains 'yes'.
Another way would be to add a function to base:
int get_arg(foo & f) { return f.my_int; }
and make that function the friend rather than add, get_arg() would be called from each derived's add() in order to get the value to work with but get_arg is not itself virtual.
You might want to look here:
https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Virtual_Friend_Function
Intent
Simulate a virtual friend function.
Solution and Sample Code
Virtual friend function idiom makes use of an extra indirection to
achieve the desired effect of dynamic binding for friend functions. In
this idiom, usually there is only one function that is a friend of the
base class of the hierarchy and the friend function simply delegates
the work to a helper member function that is virtual. The helper
function is overridden in every derived class, which does the real job
and the friend function just serves as a facade.
class Base {
public:
friend ostream& operator << (ostream& o, const Base& b);
// ...
protected:
virtual void print(ostream& o) const
{ ... }
};
/* make sure to put this function into the header file */
inline std::ostream& operator<< (std::ostream& o, const Base& b)
{
b.print(o); // delegate the work to a polymorphic member function.
return o;
}
class Derived : public Base {
protected:
virtual void print(ostream& o) const
{ ... }
};
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 2 classes (firstClass and secondClass) which firstClass is a friend of secondClass, and has a private nested unordered_map, which I want to access it in a function of secondClass.
So basically the code is like this:
class secondClass;
typedef unordered_map STable<unsigned, unordered_map<unsigned, double> > NESTED_MAP;
class firstClass{
friend class secondClass;
void myfunc1(secondClass* sc){
sc->myfunc2(&STable);
}
private:
NESTED_MAP STable;
};
class secondClass{
public:
void myfunc2(NESTED_MAP* st){
//Here I want to insert some elements in STable.
//Something like:
st[1][2]=0.5;
}
};
int main(){
firstClass fco;
secondClass sco;
fco.myfunc1(&sco);
return 0;
}
I know that it should be trivial, but I don't know how to solve it.
Any idea? (I changed the code and the question to make it more clear)
A friend class is allowed to access any private member, so you can simply invoke methods and modify properties as you would do if they had been public.
Here the documentation, it says:
The friend declaration appears in a class body and grants a function or another class access to private and protected members of the class where the friend declaration appears.
That said, by looking at your example, I'd rather change the place where to put the friend keyword, for it looks to me that myfunc2 ought not to be public.
It follows an example where I applied the above suggestion and that shows how to deal with private members from a friend class:
#include<unordered_map>
using namespace std;
class firstClass;
class secondClass{
friend class firstClass;
private:
void myfunc2(unordered_map<unsigned,double>& map){
map[1]=0.5;
}
};
class firstClass{
public:
void myfunc1(secondClass* sc){
// here firstClass is accessing a private member
// of secondClass, for it's allowed to do that
// being a friend
sc->myfunc2(STable);
}
private:
unordered_map<unsigned,double> STable;
};
int main(){
firstClass fco;
secondClass sco;
fco.myfunc1(&sco);
return 0;
}
Can i put definition of friend function / class inside another class? I mean something like this:
class Foo
{
friend void foo() {} // 1
friend class Bar {}; // 2
};
gcc compiles friend function, but can't compile friend class.
You can define a friend function in the friend declaration, and it has interesting behavior that cannot be obtained any other way (in the case of the enclosing type being a template).
You cannot define a friend class in the friend declaration, and there is no need for that. If you want to create a new type inline with full access, you can just create a nested type. Being a member it will have full access to the enclosing type. The only difference is that the type will not be found at namespace level, but you can add a typedef if needed (or alternatively, define the class at namespace level and just declare the friendship inside the class).
class Outer {
int x;
class Inner {
static void f( Outer& o ) { o.x = 5; } // fine
};
};
n3337 11.3/2
A class shall not be defined in a friend declaration. [ Example:
class A {
friend class B { }; // error: cannot define class in friend declaration
};
—end example ]
But you can use something like
class Foo
{
friend void foo() {} // 1
class Bar { };
friend class Bar; // 2
};
You can make a nested class which, according to defect report 45, has access to the private members of the class. Is this what you meant?
"A nested class is a member and as such has the same access rights as any other member."
This may not work in all compilers because prior to this C++ standards defect report, nested classes were given no special access.
Change the code to:-
class Foo
{
friend void foo() {} // 1
friend class Bar ; // 2
};
I encountered this problem when implementing a class:
class Cell {
bool isAlive;
int numNeighbours;
//...omit irrelavent private members
public:
Cell(); // Default constructor
~Cell(); // Destructor
void setLiving();
....
};
void Cell::setLiving(){
isAlive=true;
}
class Grid{...
friend std::ostream& ::operator(std::ostream& out, const Grid &g);
};//...omit
std::ostream& ::operator<<(std::ostream &out, const Grid &g){
int i,j;
for(i=0;i<g.gridSize;i++){
for(j=0;j<g.gridSize;j++){
if(**g.theGrid[i][j].isAliv*e*) out<<"X";
else out<<"_";
}
out<<endl;
}
return out;
}
The complier said that "isAlive" is a private member so I can't call it that way
I think the problem is at "g.theGrid[i][j].isAlive"
I tried to friend class Grid but it didnt help
You mentioned operator<< — it's most likely a free function, so it needs to be declared as friend to be able to access private members.
class Cell {
friend std::ostream& operator<<(std::ostream&, const Grid&);
// ...
};
The class member isAlive is private, so the operator didn't have the right to access it, you need to put a friend declaration in the body of Cell's definition.
class Cell {
friend std::ostream& operator<<(std::ostream&, const Cell&);
// ...
};
This line
if(**g.theGrid[i][j].isAlive) out<<"X"
Is accessing the private member 'isAlive'. I assume theGrid is a two dimensional array of Cell objects. You need a getLiving() method defined. Then use it here.
isAlive is private, declare it as public...
EDIT1:
class Cell {
public:
bool isAlive;
Update:
private members of a class are accessible only from within other members of the same class or from their friends.
protected members are accessible from members of their same class and from their friends, but also from members of their derived classes.
Finally, public members are accessible from anywhere where the object is visible.