C++ 如何访问类的私有数据成员中的方法/函数

C++ 如何访问类的私有数据成员中的方法/函数,c++,oop,design-patterns,C++,Oop,Design Patterns,请看一下代码示例 A.dll将使用B.dll中的类B b是a类的私人会员 现在,有一个模块C(C.dll或C.exe),C可以访问模块a,但不能访问模块B。但我们希望C可以调用B的方法,我如何调整我们的设计以接近这一点 我们无法修改B.dll,因为它是第三方模块 我们可以对类A做一些更改,我们不想在A中公开两个方法来直接调用B方法,例如(我认为这不是一个好的设计) A::B_方法1(){B->B_方法1()} A::B_methods2(){B->B_methods2()} 我们也不想直接公开

请看一下代码示例

  • A.dll将使用B.dll中的类B
  • b是a类的私人会员
  • 现在,有一个模块C(C.dll或C.exe),C可以访问模块a,但不能访问模块B。但我们希望C可以调用B的方法,我如何调整我们的设计以接近这一点

    • 我们无法修改B.dll,因为它是第三方模块

    • 我们可以对类A做一些更改,我们不想在A中公开两个方法来直接调用B方法,例如(我认为这不是一个好的设计)

      A::B_方法1(){B->B_方法1()}

      A::B_methods2(){B->B_methods2()}

    • 我们也不想直接公开私有数据成员b,比如

      const B*A::getB(){return B;}

    你知道吗?非常感谢

    添加一些评论:

    构建B的实例非常复杂(或需要一些特殊参数)。我们只能使用A来构建B。因此,如果C想要访问/调用B的函数,C必须通过A使用。

    Module A.dll
    
    class A
    {
    public:
        A ();
        virtual ~A();
    
    private:
        B* b; 
    
    }
    
    Module B.dll
    
    #ifdef SDK_DLL
    #define HLAPI __declspec(dllexport)
    #else
    #define HLAPI __declspec(dllimport)
    #endif
    
    class HLAPI B
    {
    public:
        B ();
        virtual ~B();
    
    public:
        B_method1();
        B_method2();
    }
    

    我认为,当你调用类A的方法时,直接调用它的私有成员B的方法,这是一个不错的设计,因为B只是提供了一种服务,A使用它,但隐藏了它的用法。当您使用提供邮件等功能的库时,也会发生这种情况-这是正常的

    但是,我建议在第三方模块B上引入a或a,这样可以保持它的可交换性,允许您对B进行更多抽象,还可以引入一些其他方法。 使用来自“无处不在”的直接调用将第三方模块绑定到代码时要小心——API更改可能会导致大量维护工作。但也要记住,您不应该封装所有内容,尤其是不应该封装具有数千个函数的API

    我知道这些决定并不容易,因为它们最终会导致大量的工作(或时间/金钱的损失),所以要振作起来;-) 顺便说一句,如果你还没有它们,我真的可以推荐书“设计模式”(由Gamma等著)、“企业模式”(由Fowler著)和“有效的C++”(由Meyers著)


    约斯特:

    < P>让我们考虑语言

    的可能性。
  • 暴露B成员(由于问题限制,不可行)
  • 让C成为a的朋友(我认为这也是不可行的,我知道这是巨大的)
  • 使B成为a的受保护成员并私下从a派生C
  • 提供访问函数或其他方式,以获得A对B执行所需操作(复合访问函数,通过facade/Adapter进行抽象)
  • 我会选择1和4的混合。我将把A的B成员隔离成一个带有门面/适配器接口的“代理”对象,然后公开这个对象,而不是公开B本身

    如果你能给我们更多关于A,B和C的语义的细节,所有这些都会更适合你的需要


    希望能有所帮助。

    你能澄清一下吗?您想调用B之外的私有B成员函数?@NikosC。对一个新的模块C,C想访问B函数。但是C不能访问模块B,只能访问模块A。那么我想B_method1()之前的
    public:
    说明符是一个拼写错误,您想写
    private:
    ,对吗?@NikosC。不,B的方法是公开的。但是构建B的实例是非常复杂的,我们只能使用A来创建B。因此,如果C想要访问B,C只能通过A来使用。因此,对于我最初的评论,答案应该是“否”。您不想调用B的私有成员函数,所以可以使用getter函数。见答案。