Предполагая, что ваш интерфейс PluginLoader
содержит больше, чем просто методы Register...
, и вы хотите манипулировать загрузчиками через этот интерфейс, но предоставляя отдельный канал связи между плагином и загрузчиком, вы можете просто создать другой интерфейс, PluginRegistra
, возможно , который будет иметь открытые Register...
методы.
Унаследуйте от него приватно в своем загрузчике плагинов и внедрите методы Register...
как частные функции в загрузчике. Никто не может получить доступ к методам Register...
через класс плагина, им нужен доступ к ним через интерфейс PluginRegistra
, и только загрузчик может преобразовать себя в этот тип, поскольку наследование является частным.
Теперь просто передайте загрузчик плагину точно так же, как сейчас; метод плагина Load()
теперь принимает интерфейс PluginRegistra
. Дружба не нужна. Только загрузчик плагинов может выдавать себя как экземпляр PluginRegistra
из-за частного наследования.
В примере, как и было запрошено, обратите внимание, что компилятор не встречался.
class PluginLoader
{
public:
virtual void LoadPlugin(Plugin*) = 0;
};
class PluginRegistra
{
public:
virtual void RegisterPlugin(Plugin*) = 0;
virtual void RegisterFunction(int, Plugin*) = 0;
};
class Plugin
{
public:
virtual void Load(PluginRegistra&) = 0;
}
class PlugImp : public Plugin
{
public:
virtual void Load(PluginRegistra& oPLoader)
{
//Do stuff
oPLoader.RegisterPlugin(this);
}
}
class LoaderImp : public PluginLoader : private PluginRegistra
{
public :
virtual void LoadPlugin(Plugin* plugin)
{
plugin.Load(this);
}
private :
virtual void RegisterPlugin(Plugin*)
{
}
virtual void RegisterFunction(int, Plugin*)
{
}
}