2012-01-06 3 views
0

У меня есть два частных вложенных класса, которым нужно будет получить доступ к частному члену в другом классе. Я подумал о том, чтобы поставить класс, который должен получить доступ к частному члену как другу в доступном классе, однако я получаю сообщение об ошибке, что A :: m_nData является приватным, поэтому я не могу получить к нему доступ. В любом случае, сообщая компилятору, что мне нужно получить доступ к частному члену A :: m_nData в D :: DoSomething()?Друг внутри частного вложенного класса

Вот пример того, что я пытаюсь сделать:

Файл Ах

class A 
{ 
    class D; 

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

    private: 
     friend class D; 

     int m_nData; 
}; 

Файл a.cpp:

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

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

Файл Bh:

#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++; 
       }; 
     }; 
}; 
+0

Почему должны '' C' и D' быть вложены в 'b'? Какое преимущество вы это понимаете? – ildjarn

+0

@ildjarn: В реальном случае использования A определяет 4 делегата, которые могут быть установлены. B действует как менеджер A. Мне пришлось удалить много кода, но C и D - это оболочка, которая вызывает обратный вызов A, используя указатель A. В приведенном выше примере я изменил их на значение int. – thewalrusnp

+0

Это не ответит, почему они должны быть _nested_ classes ... Почему они вложены внутри 'B'? – ildjarn

ответ

1

Вам нужны две дружеские отношения здесь. Один, чтобы сообщить A о приватном B::D, а другой, чтобы дать B::D доступ к личным данным в A.

Declare (включить) класс B до объявления класса А.

Тогда в class B, добавьте:

friend class A; 

Это позволяет класса А знать о частном B::D.

Тогда в class A заменить:

friend class D; 

с:

friend class B::D; 
+1

@KerrekSB: 'friend class B :: D' не предоставляет доступ к' B :: D', он позволяет получить доступ к нему. Если мой кофе не ударит меня сегодня утром. –

+1

@DrewDormann: Нет, неудача кофе на моей стороне! Комментарий удален! –

+0

@DrewDormann: Я не могу включить класс B в A.h, так как я бы получил рекурсивное включение, поскольку B.h уже включает A.h. – thewalrusnp