我有一个班级 - PluginLoader
,可以处理另一个班级Plugin
来执行其功能。 Plugin
类使用PluginLoader
中的一些函数。这两个类都是抽象基类,因此我不能将Plugin
声明为PluginLoader
的朋友。我不希望Plugin
使用的函数在PluginLoader
的公共界面中可用,因为它们与PluginLoader
的用户无关。这是个常见的问题吗?怎么解决?
编辑:代码示例
class PluginLoader
{
public:
virtual void RegisterPlugin(Plugin*) = 0;
virtual void RegisterFunction(int, Plugin*) = 0;
};
class Plugin
{
public:
virtual void Load(PluginLoader&) = 0;
}
class PlugImp : public Plugin
{
public:
virtual void Load(PluginLoader& oPLoader)
{
//Do stuff
oPLoader.RegisterPlugin(this);
}
}
虽然我希望RegisterPlugin
类可以使用Plugin
,但是对于其他PluginLoader
类用户来说,没有任何意义。
EDIT2:@chubsdad
#include <iostream>
using namespace std;
class PluginLoader;
class Plugin
{
public:
virtual void Register(PluginLoader&) = 0;
virtual ~Plugin() = 0;
};
class PluginLoader
{
public:
virtual void Load() = 0;
virtual ~PluginLoader() = 0;
private:
friend class Plugin;
virtual void RegisterPlugin(Plugin&) = 0;
};
class PluginImp : public Plugin
{
public:
void Register(PluginLoader& oPLoader)
{
oPLoader.RegisterPlugin(*this);
}
};
class PluginLoaderImp : public PluginLoader
{
public:
void Load()
{
Plugin* pP = new PluginImp();
pP->Register(*this);
}
private:
void RegisterPlugin(Plugin& oP)
{
cout << "PluginLoaderImp::RegisterPlugin" << endl;
}
};
int main()
{
PluginLoader* pPLoader = new PluginLoaderImp();
pPLoader->Load();
}
这会抛出编译器错误:
main.cpp: In member function ‘virtual void PluginImp::Register(PluginLoader&)’:
main.cpp:22: error: ‘virtual void PluginLoader::RegisterPlugin(Plugin&)’ is private
main.cpp:30: error: within this context
这给我们带来了完整的循环。或者有什么我想念的东西?
答案 0 :(得分:2)
在OP有代码段之前的响应
我没有看到你指出的朋友的问题。两个抽象类可以是彼此的朋友。绝对没有问题。
以下是我猜你所说的......(只是示例说明代码)
struct pluginloader;
struct plugin{
public:
void publicm(pluginloader &r);
virtual ~plugin() = 0; // abstract
private:
void privatem(pluginloader &r); // may be virtual in real code
};
struct pluginloader{
public:
void publicm(){};
virtual ~pluginloader() = 0; // abstract
private:
void privatem(){} // may be virtual in real code
friend struct plugin; // friend declaration
};
void plugin::publicm(pluginloader &r){
r.privatem(); // use private methods of pluginloader
}
void plugin::privatem(pluginloader &r){
r.privatem(); // use private methods of pluginloader
}
plugin::~plugin(){}
pluginloader::~pluginloader(){}
struct APlugin : plugin{
~APlugin(){}
};
struct ALoader : pluginloader{
~ALoader(){}
};
int main(){
APlugin apl;
ALoader ald;
apl.publicm(ald);
}
答案 1 :(得分:1)
将功能移出PluginLoader
。
编辑:考虑到问题的模糊性,我或许应该提一下,您可以通过传递提供函数的对象将一堆相关函数作为参数传递。并且您可以从提供函数的类继承。等等。
干杯&amp;第h。,
答案 2 :(得分:1)
假设您的PluginLoader
接口不仅包含Register...
方法,并且您希望通过该接口操作加载器,而是在插件和加载器之间提供单独的通信通道,您只需创建另一个接口{也许,{1}}会有公共PluginRegistra
方法。
在插件加载器中私有地继承它,并在加载器中将Register...
方法实现为私有函数。没有人可以通过插件类访问Register...
方法,他们需要通过Register...
接口访问它们,只有加载器可以将自身转换为该类型,因为继承是私有的。
现在只需将加载程序传递给插件,就像现在一样;插件的PluginRegistra
方法现在采用Load()
接口。不需要友谊。由于私有继承,只有插件加载器可以将其自身作为PluginRegistra
的实例。
一个例子,根据要求,注意这没有看到编译器。
PluginRegistra