Search code examples
c++inheritanceinner-classesfriend

Can a derived class access a private method of a protected inner class of the parent class that is a friend of the inner class?


Considering this class:

class Matchable
{
  protected:
    class Match {
      friend class Matchable;

      void append( const Match& match ) {}
    };

  public:
    virtual bool match( const Source& source ) = 0;
};

... where the outer class Matchable is a friend of the inner class Match, and considering this class:

class Literal : public Matchable {

  bool match( const Source& source ) override {
    Matchable::Match m;
    Matchable::Match cm;

    m.append( cm );

    return true;
  }

}

... where Literal is derived from Matchable, I seem to be able to instantiate Matchable::Match in Literal::match() without a problem, yet I am unable to call the private method Matchable::Match::append(), where I expected Literal to inherit the "friendliness" of Matchable.

Is this expected behavior and if so, is there a way to make Literal access private methods of its parent inner class Match?


Solution

  • Yes, this is expected behavior. See friend declaration

    Friendship is not inherited (your friend's children are not your friends)

    You might provide a delegate method in Matchable:

    class Matchable
    {
      protected:
        class Match {
          friend class Matchable;
          void append( const Match& match ) {}
        };
        void appendMatch( Match& match, const Match& matched ) { 
            match.append(matched);
        }
    
      public:
        virtual bool match( const Source& source ) = 0;
    };
    

    then

    class Literal : public Matchable {
    
      bool match( const Source& source ) override {
        Matchable::Match m;
        Matchable::Match cm;
    
        appendMatch(m, cm);
    
        return true;
      }
    
    }
    

    Otherwise you might make Match::append public (which make friend declaration meaningless).