In code below:
class B {
int x;
int y;
};
class A {
friend class Other;
friend class A;
int a;
B* b;
public:
A(){ b = new B();}
};
struct Other {
A a;
void foo() {
std::cout << a.b->x; // error
}
};
int main() {
Other oth;
oth.foo();
}
The indicated line fails with:
t.cpp:22:19: error: 'x' is a private member of 'B'
std::cout << a.b->x;
^
t.cpp:7:5: note: implicitly declared private here
int x;
Why friendship is not working when referring from class member to other class member?
This line:
std::cout << a.b->x;
involves accessing a private member of A (b) and a private member of B (x) within class Other. While A gave access privileges to Other, B did not, hence the error. If you want this to work, you'll need to add:
class B {
friend class Other;
};
Side-note, this declaration is meaningless:
class A {
friend class A;
};
A class already has access to its own private members. So calling it its own friend is redundant.
Although this is a weird use of friends, I assume it is for learning purposes. That said, you should fix your friends definition like this:
class B{
friend class Other; // Because you access private member x from Other::foo()
int x;
int y;
};
class A{
friend class Other; // Because you access private member b from Other::foo()
int a;
B* b;
public:
A(){ b = new B();}
};
struct Other{
A a;
void foo(){
// Access A's private member b
// Access B's private member x
std::cout << a.b->x;
}
};
Try this:
class B{
friend class Other;
int x;
int y;
};
Related
class A{
public:
void printer(){
B obj;
obj.private_data = 10; // <- fails, says member inaccessible
}
}
class B{
friend void A::printer();
private:
int private_data;
}
is it possible for printer function to access private members of class B? i tried to pass an obj of B as arg to printer but it still failed
Class A doesn't know about B to use it. Hence, postpone the definition of the function printer() until you define B, and if you need an instance of B to be a member var in A then make a forward declaration for B to declare a B* in A.
Hence, use something like what follows:
class A {
public:
void printer();
};
class B {
friend void A::printer();
private:
int private_data;
};
void A::printer() {
B obj;
obj.private_data = 10; // <- No longer fails
std::cout << obj.private_data;
}
int main() {
A a;
a.printer();
}
Demo
Why Friend Function cannot access private members of a class?
They can, but you may need to split the definition of the class up a bit.
Imaginary files added:
Define A (file a.hpp):
class A {
public:
void printer();
};
Define B (file b.hpp):
#include "a.hpp" // B must see the definition of A to befriend a member function
class B {
friend void A::printer();
private:
int private_data;
};
Define A's member function (file a.cpp):
void A::printer() {
B obj;
obj.private_data = 10;
}
To access B, you first need to define it. Thus, you can just declare the method printer and define it after you have defined the class B.
class A {
public:
void printer();
};
class B {
private:
friend class A;
int private_data;
};
void A::printer() {
B obj;
obj.private_data = 10;
}
Note, you probably want to move your methods out of your class definition anyways and into a separate .cpp file. Methods defined inside the class are implicitly marked as inline which might not be what you expect.
I have the following code:
#include <iostream>
class A {
private:
int a;
public:
void setA(int a_);
friend int B::getA();
};
class B : public A {
public:
int getA();
};
void A::setA(int a_) {
a = a_;
}
int B::getA() {
return a;
}
int main() {
B myB;
myB.setA(9);
std::cout << myB.getA()<< std::endl;
return 0;
}
Compiling with g++ yields:
friend.cpp:10:16: error: use of undeclared identifier 'B'
friend int B::getA();
My thinking is that when the compiler is going through the class A definition, it does not yet know about class B. Therefore, I can forward declare B to take care of this problem:
#include <iostream>
class B;
class A {
...
That doesn't quite work:
friend.cpp:10:16: error: incomplete type 'B' named in nested name specifier
friend int B::getA();
It looks like the compiler isn't able to resolve the function as it is given.
How can I make a derived class function a friend in the base class?
Your code seems to violate the basic concept of data encapsulation. To resolve it, either make A::a protected, as #rici suggested, or define a getter in class A.
class A {
private:
int a;
public:
void setA(int a_);
virtual int getA();
};
class B : public A {
public:
int getA();
};
void A::setA(int a_) {
a = a_;
}
int A::getA() {
return a;
}
int B::getA() {
return A::getA();
}
class A
{
private:
int a,b,c;
public:
virtual int get()=0;
friend class B;
};
class B{
//here I want to access private variables of class A that is a, b and c
};
class C:public class A
{
int get(){
//some code
}
};
How to access private members of class A in class B. I cannot create an object of class A since it is abstract. I somehow have to use an object of class C to do that but how?
class A {
friend class B;
private:
int x;
public:
A() : x(42) {}
};
class C : public A {
};
class B {
public:
int reveal_secrets(C &instance){
// access private member
return instance.x;
}
int reveal_secrets(){
// access private member of instance created inside B
C instance;
return instance.x;
}
};
void print_secrets(){
C instance;
B accessor;
std::cout << accessor.reveal_secrets(instance) << ", " << accessor.reveal_secrets() << std::endl;
}
class B will have to have an instance object to work with in the first place. That instance object is what B will look at in order to access a, b, etc .
Ok I'm totally frazzled on this. Code is begin to swim around the screen...must sleep.
So! Ok, troubled by nested classes and friends.
here is the pseudo-code
class A{
public:
//constructor
// member functions
private:
class B{
//private
int a();
};
class C{
//private
int b();
};
};
So once an object of type A has been created, I would like it to access a() and b(). I know that I have to use a friend function for this. So where should I put friend class A. Is that the right expression?.
If you would like to access a() and b() from within class A you need to place the friend declaration inside of class B and class C. However, a() and b() are not members of class A so you cannot access them in the way you are thinking. Instead you also need to add forwarding functions to A.
class A
{
public:
//constructor
// member functions
private:
class B
{
//private
int a();
friend A; // <-- make A a friend
};
class C
{
//private
int b();
friend A; // <-- make A a friend
};
public:
// forwarding function for a
int a()
{
return bdata_.a();
}
// forwarding function for b
int b()
{
return cdata_.b();
}
private:
B bdata_;
C cdata_;
};
How can I create two classes that have member pointers to each other's class type, with full access to each other's data? In other words, I need two classes like this:
class A
{
protected:
B *p;
};
class B
{
protected:
A *p;
};
I'm having trouble with it because I'm not up to par with C++ conventions, and obviously, class A can't declare a class B because B is declared later in the code.
Thanks for the help
You should use forward class declaration.
//in A.h
class B; // forward declaration
class A
{
protected:
B *p;
friend class B; // forward declaration
};
//in B.h
class A; // forward declaration
class B
{
protected:
A *p;
friend class A; // forward declaration
};
class B;
class A {
friend class B;
protected:
B *p;
};
class B {
friend class A;
protected:
A *p;
};
Note that any member functions of A which actually use the members of B will have to be defined after the definition of B, for example:
class B;
class A {
friend class B;
protected:
B *p;
A *getBA();
};
class B {
friend class A;
protected:
A *p;
};
A *A::getBA() { return p->p; }
you must use forward declaration like:
class B;
class A{
...
friend class B;
};
class A
{
protected:
class B *p;
};
If you want to declare friendship, you need a forward declaration:
class B;
class A
{
friend class B;
protected:
B *p;
};
class B;
class A
{
protected:
B *p;
friend class B;
};
class B
{
protected:
A *p;
friend class A;
};
You could use a forward declaration by doing class B; above class A
simple use:
class B;
class A
{
protected:
B *p;
friend class B;
};
class B
{
protected:
A *p;
friend class A;
};
Using class B; means a forward declaration and this basically tells the compiler: "class B exists somewhere".