Comment accéder à une variable membre privée de classe de données d'une autre classe dérivée dont la classe mère est une classe d'ami de la classe de données?

StackOverflow https://stackoverflow.com/questions/851041

Question

J'ai trois classes:

  1. Une classe support de données CDataHolder, qui utilise un motif Pimpl

    class CDataHolder
    {
    public:
      // ...
    private:
    friend class CBase;
    struct PImpl;
    PImpl* iPimpl;
    };
    
  2. Une classe de base CBase, qui ont besoin d'accéder au membre iPImpl dans CDataHolder, il est donc une classe d'ami de CDataHolder

    class CBase: 
    {
    protected:
    CDataHolder::Pimpl* getDataHolderPimpl();
    };
    
  3. Une classe dérivée CDerived de CBase, qui ont besoin d'accéder au même membre iPimpl aussi. Ici se produit un problème. La classe dérivée ne peut pas utiliser le membre iPimpl bien que sa classe parente est une classe d'ami. comme ceci:

    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"
    }
    };
    

    Il y a beaucoup de classes dérivées, il est donc pas une bonne façon pour chaque classe dérivée de mettre une ligne « classe ami CDerivedXXX » en classe CDataHolder. Comment résoudre ce problème? Y a-t-il une meilleure manière de faire cela? Merci à l'avance.

Était-ce utile?

La solution

Puisque vous avez déclaré dans la partie struct PImpl privée de classe CDataHolder, seuls amis de CDataHolder peuvent accéder à la même chose. Pourquoi ne pas vous mettre en avant une déclaration dans la section <=> publique ou mieux encore avant la classe CDataHolder?

Autres conseils

ami est (à juste titre) très limité et ne peut être héritée. Je déteste éluder la question, mais peut-être soit A) vous avez besoin d'un accès public à Pimpl ou certains de ses aspects, ou B), vous devez la classe DataHolder pour faire quelque chose avec Pimpl pour vous.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top