0
votes

I have a derived class that implements an interface(abstract class) in C++. This interface has a couple of protected functions whose implementation are defined in derived class.

Now I'm trying to access these protected functions in derived class from an external class, by declaring the external class as a friend in derived class. However, the compiler still complains that I cannot access the protected member functions.

For example: I have class ConnectSession implementing IConnectSession. And an external class called SystemProcess who wants to access protected member function HandlePriviledgedRequest.

In IConnectSession.h

class IConnectSession{
protected:
    virtual void HandlePriviledgedRequest() = 0;
}

In ConnectSession.h

class ConnectSession : public IConnectSession{
protected:
    void HandlePriviledgedRequest() override {/* func definition */}
    friend class SystemProcess;
}

In friend class I try to access HandlePriviledgedRequest()

SystemProcess.cpp

SystemProcess::ApplyConfiguration(){
    std::shared_ptr<IConnectSession> sessionPtr = new ConnectSession();
    sessionPtr->HandlePriviledgedRequest(); // compile error
}

It throws an error from compiler saying I cannot access protected members even if I have already declared SystemProcess as a friend. Since friend declarations are not inherited I particularly declare them in ConnectSession. Why does it not work and how to fix it? Thanks.

2
In general, Iā€™d expect member functions of an interface to be public. Why are these protected? ā€“ Pete Becker
@PeteBecker, I would like to make sure some interface methods are only called within certain classes but not in others. So the friend membership is only granted to those certain classes. ā€“ Vince

2 Answers

2
votes

That's because your access is thru the IConnectSession interface, sessionPtr, and your friendship is only with the derived class, not the base class.

2
votes

Access control is something that only applies at compile time. In

SystemProcess::ApplyConfiguration(){
    std::shared_ptr<IConnectSession> sessionPtr = new ConnectSession();
    sessionPtr->HandlePriviledgedRequest(); // compile error
}

even though sessionPtr gets set to an instance of ConnectSession, its static type is IConnectSession and that is what access control is ran against. Since SystemProcess isn't a friend of IConnectSession it is not allowed to access HandlePriviledgedRequest().

You'll need to make it a friend of IConnectSession to get it to compile.