Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何向类公开公共接口的子集_C++_Oop - Fatal编程技术网

C++ 如何向类公开公共接口的子集

C++ 如何向类公开公共接口的子集,c++,oop,C++,Oop,我有一个类-PluginLoader,它处理另一个类Plugin来执行它的功能Plugin类使用了PluginLoader中的一些函数。这两个类都是抽象基类,所以我不能将Plugin声明为pluginload的朋友。我不希望PluginLoader的公共界面中有PluginLoader使用的函数,因为它们与PluginLoader的用户没有关联。这是一个普遍的问题吗?如何解决 编辑:代码示例 class PluginLoader { public: virtual void R

我有一个类-
PluginLoader
,它处理另一个类
Plugin
来执行它的功能
Plugin
类使用了
PluginLoader
中的一些函数。这两个类都是抽象基类,所以我不能将
Plugin
声明为
pluginload
的朋友。我不希望
PluginLoader
的公共界面中有
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
类的其他用户看到它

编辑2:@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();
}

这给我们带来了一个完整的循环。或者我缺少了什么?

将函数移出
插件加载程序

编辑:鉴于问题的模糊性,我或许应该提到,通过传递提供函数的对象,可以将一组相关函数作为参数传递。您可以从提供函数的类继承。等等


干杯&hth.,

在OP有代码片段之前的响应

我看不出你指出的朋友之间的问题。两个抽象类可以是彼此的朋友。这绝对没有问题

以下是我猜您所指的…(只是一个示例插图代码)


假设您的
PluginLoader
接口包含的不仅仅是
Register…
方法,并且您希望通过该接口操作加载程序,但在插件和加载程序之间提供一个单独的通信通道,那么您可以简单地创建另一个接口,
PluginRegistra
,它将有公共
注册…
方法

在插件加载程序中以私有方式继承它,并在加载程序中将
Register…
方法作为私有函数实现。没有人可以通过plugin类访问
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*)
      {
      }
}

你的例子现在起作用了。但是当你从
插件
插件信息
派生时会发生什么?顺便说一句,我想你指的是插件加载程序而不是插件信息?嗯,所以
朋友
完全是一种编译时机制…:(.为什么我没想到?是的。抽象类不能实例化。就是这样。它不会影响友谊机制,如插图所示。有人能详细解释一下吗?:(.我试图做它要求我做的事情,但没有结果。这根本不是人为的。从逻辑上讲,你的插件加载器有两个独立的接口,一个是它向插件公开以允许它们注册的接口,另一个是它向世界公开的接口,所以就这样实现它。@Len Holgate:明白了。谢谢。顺便说一句,
PluginLoader
应该继承
IRegisterPlugins
中的
protected
。否则你不能将
这个
作为
IRegisterPlugins
传递给函数。我认为私有继承应该可以工作鉴于上面的示例,如果你让这两个接口继承,我想你需要保护。
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);
}
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*)
      {
      }
}