Где в производном или базовом классе я должен объявить класс друга?
У меня есть производный класс, который реализует интерфейс (абстрактный класс) в C++. Этот интерфейс имеет несколько защищенных функций, реализация которых определена в производном классе.
Теперь я пытаюсь получить доступ к этим защищенным функциям в производном классе из внешнего класса, объявив внешний класс как друга в производном классе. Тем не менее, компилятор все еще жалуется, что я не могу получить доступ к защищенным функциям-членам.
Например: у меня есть класс ConnectSession
реализации IConnectSession
, И внешний класс называется SystemProcess
кто хочет получить доступ к функции защищенного члена HandlePriviledgedRequest
,
В IConnectSession.h
class IConnectSession{
protected:
virtual void HandlePriviledgedRequest() = 0;
}
В ConnectSession.h
class ConnectSession : public IConnectSession{
protected:
void HandlePriviledgedRequest() override {/* func definition */}
friend class SystemProcess;
}
В классе друга я пытаюсь получить доступ HandlePriviledgedRequest()
SystemProcess.cpp
SystemProcess::ApplyConfiguration(){
std::shared_ptr<IConnectSession> sessionPtr = new ConnectSession();
sessionPtr->HandlePriviledgedRequest(); // compile error
}
Выдает ошибку компилятора, говорящую, что я не могу получить доступ к защищенным членам, даже если я уже объявил SystemProcess
как друг. Поскольку объявления друзей не наследуются, я особенно объявляю их в ConnectSession
, Почему не работает и как это исправить? Благодарю.
2 ответа
Контроль доступа - это то, что применяется только во время компиляции. В
SystemProcess::ApplyConfiguration(){
std::shared_ptr<IConnectSession> sessionPtr = new ConnectSession();
sessionPtr->HandlePriviledgedRequest(); // compile error
}
даже если sessionPtr
устанавливается на экземпляр ConnectSession
, его статический тип IConnectSession
и это то, с чем сталкивается контроль доступа. поскольку SystemProcess
не друг IConnectSession
доступ запрещен HandlePriviledgedRequest()
,
Вы должны сделать это другом IConnectSession
чтобы получить его для компиляции.
Это потому, что ваш доступ через IConnectSession
интерфейс, sessionPtr
и ваша дружба только с производным классом, а не с базовым классом.