访问权限有限的朋友班级

发布于 2024-08-09 04:45:29 字数 357 浏览 8 评论 0原文

我想让 A 类成为 B 类的朋友。我想这样做,因为它们之间的交互非常频繁,并且 A 需要更改 B 类的内部结构(我不想使用 public 来公开)。但我想确保它只能访问少数选定的功能,而不是所有功能。

示例:

class A
{
};

class B
{
private:
    void setState();
    void setFlags();
    friend class A;
};

我希望 A 能够访问 setState 但不能访问 setFlags...是否有设计模式或实现此目的的好方法,或者我只能给出在这种情况下,完全访问还是根本没有访问?

I want to make class A friend of class B. I want to do this as these interact very much and A needs to change internals of class B (which I don't want to expose using public). But I want to make sure it has access to only a few selected functions, not all the functions.

Example:

class A
{
};

class B
{
private:
    void setState();
    void setFlags();
    friend class A;
};

I want A to be able to access setState but not setFlags... Is there a design pattern or a nice way of doing this, or am I left with giving full access or no access at all in this case?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

帥小哥 2024-08-16 04:45:29

这取决于你所说的“一个好方法”是什么意思:) 在 comp.lang.c++.moderated 我们不久前也遇到了同样的问题。您可能会看到它生成的讨论 那里

IIRC,我们最终使用了“嵌套键的朋友”方法。应用于您的示例,这将产生:

class A
{
};

class B
{
public:
     class Key{
         friend class A;
         Key();
     };

    void setState(Key){setState();}         

private:
  void setState();
  void setFlags();
};

这个想法是公共 setState() 必须使用“Key”调用,并且只有 Key 的朋友才能创建一个,因为它的构造函数是私有的。

It depends on what you mean by "a nice way" :) At comp.lang.c++.moderated we had the same question a while ago. You may see the discussion it generated there.

IIRC, we ended up using the "friend of a nested key" approach. Applied to your example, this would yield:

class A
{
};

class B
{
public:
     class Key{
         friend class A;
         Key();
     };

    void setState(Key){setState();}         

private:
  void setState();
  void setFlags();
};

The idea is that the public setState() must be called with a "Key", and only friends of Key can create one, as its ctor is private.

桃气十足 2024-08-16 04:45:29

一种方法是通过显式接口,因为接口的实现者可以选择将接口提供给谁:

class NearlyPrivateInterface {
public:
   virtual void setState() = 0;
   virtual void setFlags() = 0;
};

class A {
public:
   void attach(NearlyPrivateInterface* instanceOfB);
};

class B: private NearlyPrivateInterface {
public:
   void attach(A& a) { a.attach(this); }
};

One approach is through explicit interfaces, because the implementor of an interface can select who they give them to:

class NearlyPrivateInterface {
public:
   virtual void setState() = 0;
   virtual void setFlags() = 0;
};

class A {
public:
   void attach(NearlyPrivateInterface* instanceOfB);
};

class B: private NearlyPrivateInterface {
public:
   void attach(A& a) { a.attach(this); }
};
儭儭莪哋寶赑 2024-08-16 04:45:29

你可以做以下事情..

class A{
};

class B{
private: 
    void setFlags();
protected:
    void setState();

}; 

class RestrictedB :public B{  
    friend class A;
};

You can do following thing..

class A{
};

class B{
private: 
    void setFlags();
protected:
    void setState();

}; 

class RestrictedB :public B{  
    friend class A;
};
空袭的梦i 2024-08-16 04:45:29

您还可以使用函数指针来完成此操作:

class B
{
    void setState();
    void setFlags();

public:
    class visitor
    {
        static constexpr auto setState = &B::setState;
        friend class A;
    };
};

class A
{
    void doStuff(B& b) { (b.*B::visitor::setState)(); }
};

或者,如果您不介意在 A 内复制函数指针,则可以使语法看起来几乎正常:

class A
{
    static constexpr auto setState = B::visitor::setState; 
    void doStuff(B& b) { (b.*setState)(); }
};

示例链接:https://godbolt.org/z/Thvb6cY5s

You can also use function pointers to accomplish this:

class B
{
    void setState();
    void setFlags();

public:
    class visitor
    {
        static constexpr auto setState = &B::setState;
        friend class A;
    };
};

class A
{
    void doStuff(B& b) { (b.*B::visitor::setState)(); }
};

Or, if you don't mind duplicating function pointers inside A, you can make the syntax look almost normal:

class A
{
    static constexpr auto setState = B::visitor::setState; 
    void doStuff(B& b) { (b.*setState)(); }
};

Example link: https://godbolt.org/z/Thvb6cY5s

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文