2009-05-12 4 views
2

У меня есть три класса:Как получить доступ к переменной частного члена класса данных из другого производного класса, родительский класс которого является классом друзей класса данных?

  1. Держатель данных класса CDataHolder, который использует шаблон Pimpl

     
    class CDataHolder 
    { 
    public: 
        // ... 
    private: 
    friend class CBase; 
    struct PImpl; 
    PImpl* iPimpl; 
    }; 
    
  2. Базовый класс CBase, которые должны получить доступ к элементу iPImpl в CDataHolder, так это является другим классом CDataHolder

     
    class CBase: 
    { 
    protected: 
    CDataHolder::Pimpl* getDataHolderPimpl(); 
    }; 
    
  3. Производного класса CDerived из CBase, которые должны получить доступ к Сэму e iPimpl. Здесь возникает проблема. Производный класс не может использовать член iPimpl, хотя его родительский класс является классом друзей. как это:

     
    class CDerived : public CBase 
    { 
    public: 
    void doSth() { 
        CDataHolder::Pimpl *pImpl = getDataHolderPimpl(); // this line raises an error: 
                    // "illegal access from CDataHolder to protected/private member CDataHolder::PImpl" 
    } 
    }; 
    

    Есть множество производных классов, так что это не является хорошим способом для каждого производного класса поставить линию «друг класса CDerivedXXX» в классе CDataHolder. Как преодолеть эту проблему? Есть лучший способ сделать это? Заранее спасибо.

ответ

2

Поскольку вы объявили struct PImpl в закрытой части класса CDataHolder только друзья CDataHolder могут получить доступ к тем же самым. Почему бы вам не добавить форвардную декларацию struct PImpl в общедоступный раздел или даже лучше, чем класс CDataHolder?

+0

Спасибо и ваш быстрый ответ. Он работает после публикации объявления «struct Pimpl» для общественности. Я неправильно понял данные об ошибках, приведенные выше, что означает, что он не может получить доступ к типу CDataHolder :: Pimpl. Тип нужен публичный доступ. Большое спасибо. – douyw

1

Друг (по праву) очень ограничен и не может быть унаследован. Мне не нравится задавать вопрос, но, может быть, A) вам нужен публичный доступ к PImpl или какой-либо его аспект, или B) вам нужен класс DataHolder, чтобы что-то сделать с PImpl для вас.