1

I have two private nested classes that would need to access a private member in another class. I thought about putting the class that needs to access the private member as friend in the accessed class, however I'm getting an error that A::m_nData is private so I can't access it. Anyway of telling the compiler that I need to access the A::m_nData private member within D::DoSomething()?

Here is a sample of what I'm trying to do:

File A.h

class A
{
    class D;

    public:
        A();
        ~A() {}

    private:
        friend class D;

        int m_nData;
};

File A.cpp:

#include "A.h"
#include "B.h"

A::A()
:   m_nData(0)
{
}

File B.h:

#include "A.h"

class B
{
    public:
        B() {}
        ~B() {}

    private:
        class C
        {
            public:
                C(A* pA): m_pA(pA) {}
                virtual ~C() {}
                virtual void DoSomething() {}

            protected:
                A* m_pA;
        };

        class D: public C
        {
            public:
                D(A* pA): C(pA) {}
                virtual ~D() {}
                virtual void DoSomething()
                {
                    m_pA->m_nData++;
                };
        };
};
thewalrusnp
  • 427
  • 1
  • 4
  • 15
  • Why must `C` and `D` be nested inside `B`? What advantage do you perceive by doing that? – ildjarn Jan 06 '12 at 15:33
  • @ildjarn: In the real use-case, A is defining 4 delegates that can be set. B is acting like a manager of A. I had to remove a whole lot of code, but C and D are wrapper that call the callback of A using the A pointer. In the example I've put there, I changed those to an int value instead. – thewalrusnp Jan 06 '12 at 15:40
  • That doesn't answer why they must be _nested_ classes... Why are they nested inside of `B`? – ildjarn Jan 06 '12 at 15:41
  • Well, since it was code that was only used in the context of B, I didn't see the need to be set outside its scope. There must be a way in C++ to make it work the way it is, no? – thewalrusnp Jan 06 '12 at 15:44
  • Clearly it's _not_ only used in the context of `B` though, otherwise you wouldn't be posting this question. ;-] Ultimately your best fix here is to rethink your design. – ildjarn Jan 06 '12 at 15:45

1 Answers1

2

You need two friendships here. One to let A know about the private B::D and another to let B::D access private data in A.

Declare (include) class B before declaring class A.

Then in class B, add:

friend class A;

This allows class A to know about the private B::D.

Then in class A, replace:

friend class D;

with:

friend class B::D;
Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
  • 1
    @KerrekSB: `friend class B::D` doesn't provide access to `B::D`, it allows access from it. Unless my coffee is failing me this morning. – Drew Dormann Jan 06 '12 at 15:38
  • 1
    @DrewDormann: No, coffee failure is on my side! Comment deleted! – Kerrek SB Jan 06 '12 at 15:39
  • @DrewDormann: I can't include class B in A.h since I would get recursive inclusion as B.h already include A.h. – thewalrusnp Jan 06 '12 at 16:04
  • @golbez: In a.cpp, include b.h before a.h. You'll have to move the DoSomething() definition out of the header, but that's a good practice anyway. You're almost there. – Drew Dormann Jan 06 '12 at 16:10