4

I've been trying to write up a code to implement a member function that could access private data of a class by declaring it as a friend within the class. But my code is failing and I can't seem to figure out what's wrong with it:

#include <iostream>

using namespace std;

class A;
class B
{
    private:
    int b;       // This is to be accessed by member function of A

    public:
    friend void A::accessB();
};

class A
{
    private:
    int a;

    public:
    void accessB();
};

void A::accessB()
 {
     B y;
     y.b = 100;
     cout << "Done" << endl;
 }

int main(void)
{
    A x;
    x.accessB();
}

I am trying to access the private contents of B making use of getAccessB function which is member function of A. I have declared it as a friend. What's wrong with this?

Lokesh
  • 2,842
  • 7
  • 32
  • 47

2 Answers2

3

A::accessB is not declared at the point of the friend declaration, so you can't refer to it. You can fix this by shifting the order of definitions and declarations such that A::accessB is visible to B:

class A
{
    private:
    int a;

    public:
    void accessB();
};

class B
{
    private:
    int b;

    public:
    friend void A::accessB();
};


void A::accessB()
 {
     B y;
     y.b = 100;
     cout << "Done" << endl;
 }

Note that making a function a friend just so that it can modify your private state is a bad code smell. Hopefully you are just doing this to understand the concepts.

TartanLlama
  • 63,752
  • 13
  • 157
  • 193
  • Just one more thing. I think I got it. There's just one little confusion. If I move A::accessB() above class B in the code you have posted in your answer, then the code doesn't work. Can you explain why? – Lokesh Aug 27 '15 at 11:24
  • 1
    Because `A::accessB()` declares a variable of type `B`, which hasn't been defined yet. A forward declaration won't work there because `B` needs to be a complete type. – TartanLlama Aug 27 '15 at 11:25
  • Why B needs to be a complete type? What's the general rule to follow to determine if forward declaration would work or not? – Lokesh Aug 27 '15 at 11:26
  • 1
    See [this question](http://stackoverflow.com/questions/553682/when-can-i-use-a-forward-declaration) for what you can and can't do with forward declarations. – TartanLlama Aug 27 '15 at 11:28
1

The ordering. If you are referring to A::accessB, A must be declared by that point. Place the A class above the B, and it will work fine.

SingerOfTheFall
  • 29,228
  • 8
  • 68
  • 105