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.
Related
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.
Is there a meaning to declare friendship in the protected section, rather than in public?
For example in this code:
class Shape {
//...
protected:
friend ostream& operator<<(ostream& os, const Shape& s);
virtual void print(ostream& os) const = 0;
};
[Note that Shape is abstract]
Could I have just put the friend and the function declaration in public?
Thanks!
Is there a meaning to declare friendship in the protected section,
rather than in public?
No. The friend class has the same level of access irrespective of whether the friend declaration appears in either the public, protected or private sections of the class definition.
link
Could I have just put the friend and the function declaration in
public?
thus yes, it doesn't matter whether declaration has been found in private, public or protected part of your class.
Class 1:
class Class1{
public:
Class1(Class2 * a, int b );
~Class1();
friend ostream& operator<< (ostream& x, const Class1& c1);
private:
int b;
Class2 * a;
};
ostream& operator<< (ostream& x, const Class1& c1)
{
stream<<"("<<c1.a->label<<","<<c1.b<<")"<<endl;
return x;
}
Class2 (In another file):
class Class2
{
public :
Class2 (string label);
~Class2();
string getLabel()
{
return label;
}
private:
string label;
vector<Class1 *> c1vector;
};
Question:
I'm trying to print the label and b of an edge, but it says the label is private. Can you tell me what I'm doing wrong? Thanks.
Well, you are trying to access a private member of Class2 directly, and the private property is actually what prevents you from doing this. (And the fact that you qualified operator<< friend in Class1 doesn't change anything, label is a private member of Class2).
Either make the member public (not recommended) or provide a public member function that returns the value of this member.
You have to write in Class2 friend ostream& operator<< (ostream& x, const Class1& c1);, because only Class 1 is its friends but label if a private attibute of class2
label is private within Class2 so it cannot be access through Class or your operator<< insertion function. The simplest solution is to provide a public const get_label function in Class2 to access the label string.
A more in depth approach is to give Class2 its own print mechanism (either through a print/display/show function, or with its own operator<< that can be used to show the label.
One issue is that: label is private in Class2, you cannot directly access it inside Class1 via an instance of Class2, which is a in this case. You may need to provide getters inside Class2.
class Class2
{
public :
string getLable()
{
return label;
}
private:
string label;
};//^^other members skipped for clearance purpose
i.e. if I define operators == and + in my class in a private section, can they be accessible from main?
It works in MSVS 2008 and 2010 but for me it seems to be a bug in a compiler. Is it so?
Functions or members declared under private access specifier will not be accessible outside the class member functions.
There are 3 access specifiers for a class/struct/Union in C++. These access specifiers define how the members of the class can be accessed. Of course, any member of a class is accessible within that class(Inside any member function of that same class). Moving ahead to type of access specifiers, they are:
Public - The members declared as Public are accessible from outside the Class through an object of the class.
Protected - The members declared as Protected are accessible from outside the class BUT only in a class derived from it.
Private - These members are only accessible from within the class. No outside Access is allowed.
Friends to the rescue!
Declaring a function as friend inside another class allows that function to access all the member functions inside the class irrespective of the access specifier rules. friend It is a way to bypass the access specifier rules laid out in C++. Similary, a class declared as friend inside another class will allow the class being declared as friend to have access to all the members of the class. Note that the friend declaration can be given under any access specifer and it will have the same effect.
An source code example:
class MyClass
{
public:
int a;
protected:
int b;
private:
int c;
friend void doSomething(MyClass obj);
};
void doSomething(MyClass obj)
{
obj.a = 10; //Allowed
obj.b = 20; //Allowed,
obj.c = 30; //Allowed,
}
int main()
{
MyClass obj;
obj.a = 10; //Allowed
obj.b = 20; //Not Allowed, gives compiler error
obj.c = 30; //Not Allowed, gives compiler error
}
So in your usage if you are using friend then you can have access to the private members of the class or else your compiler is buggy you should consider changing it!
You will have to show the code to get a sensible explanation of why the compiler is accepting it. My guess is that you are implementing them as friend free functions. At any rate, for the sake of argument, assume you have:
class bar {
friend bool operator==( bar const &, bar const & ) {
return true;
}
bar operator+( bar const & ) {
return *this;
}
};
int main() {
bar a, b;
a == b; // ok
//a + b; // nok: operator+ is private from this context
}
And now the explanation. In the example, operator+ is declared as a member function inside a private section, as such, access specifiers apply and unless main is a friend of the class it will not have access to it. On the other hand operator== is implemented as a free function (even if the definition is provided inside the class braces) and access specifiers do not apply there.
The code is almost equivalent (there is a small difference when it comes to lookup) to:
class bar {
friend bool operator==( bar const &, bar const & ); // just declare as friend
//...
};
bool operator==( bar const &, bar const & ) {
return true;
}
Where it is much simpler to reason about accessibility of operator== from the main function.
Yes, it is a bug. They are accessible only by friend functions and friend classes. All other shouldn't have access to private section.
The first answer is : No. If its accessible from outside then what is the point of being it private?
However, there is a twist.
If you make main() friend of the class, then its accessible only from main(). So the second answer is : it actually depends: Only member functions and friends can access the private member of a class.
class A
{
int data; //private
friend int main(); //make main() friend of A
};
int main()
{
A a;
a.data = 100; //okay - main() is a friend of class A
}
void f()
{
A a;
a.data = 100; //error - f() is not a friend of class A
}
That means, I infer that operator== and operator+ must be friends of the class in your code.
If you haven't added a friend declaration for main (don't know if that is even possible), the answer is no, so you apparently have found a compiler bug.
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.