隐式朋友类库

时间:2019-07-16 21:59:06

标签: c++ oop

我正在开发C ++类库。这些类具有针对用户的“公共”方法,而“受保护的”方法提供保留供内部使用的额外服务。

这些类不是彼此派生的。在我当前的模型中,需要将它们明确声明为彼此的朋友。有没有更紧凑/方便的方法来达到相同的效果?


示例:

class A
{
public:
    static int ExposedA() { return 1; }
    static int ExposedB();
    static int ExposedC();

private:
    static int Internal() { return 0; }
    friend class B;
    friend class C;
};

class B
{
public:
    static int ExposedA() { return 2 + A::Internal(); }
    static int ExposedB() { return 2; }
    static int ExposedC();

private:
    static int Internal() { return 0; }
    friend class A;
    friend class C;
};

class C
{
public:
    static int ExposedA() { return 3 + A::Internal(); }
    static int ExposedB() { return 3 + B::Internal(); }
    static int ExposedC() { return 3; }

private:
    static int Internal() { return 0; }
    friend class A;
    friend class B;
};

int A::ExposedB() { return 1 + B::Internal(); }
int A::ExposedC() { return 1 + C::Internal(); }
int B::ExposedC() { return 2 + C::Internal(); }

在实践中,维护好友列表非常繁琐,并且前向引用迫使将定义移出类。

1 个答案:

答案 0 :(得分:0)

我认为简短的答案是“不”。

在评论中(供以后阅读的任何人使用),您将问题标识为“ 故意强耦合的情况”,如an answer to this question(强调我的)中所述:< / p>

  

通常,朋友类在有故意强耦合的设计中很有用:您需要在两个类之间建立特殊的关系。更具体地说,一个班级需要访问另一个班级的内部信息,而您不想使用公共访问说明符向所有人授予访问权限

答案继续说明:

  

经验法则:如果public太弱而private太强,则需要某种形式的选定访问:受保护的或朋友的(Java中的程序包访问说明符起着相同的作用)。

换句话说,如果public对您不起作用,而private对您不起作用,那么您将剩下protectedfriend。如果您也无法使用protected,那么您将在淘汰过程中陷入friend的困境。您无法更改语言(除非您想向委员会提交论文,但这完全是另一个主题)。您将尽最大努力来处理这些访问说明符。

关于哪种方式是使用这些说明符的最佳方式的问题,我没有答案。我几乎不可能知道哪种杂耍组合最适合您的情况。到目前为止,您的解决方案似乎是最好的。鉴于您的限制,没有什么比这更好的了。


  

它在类库的内部。用户应该没有访问权限,类中的库应该具有相互访问权限。

如果我正确地理解了您(可能不是),我会说您确实具有(未调试的)双重标题选项:一个供您使用,一个供最终用户使用。在标题中,您可以使函数public像这样:

// YouB.h
class B
{
public:
    static int ExposedA() { return 2 + A::Internal(); }
    static int ExposedB() { return 2; }
    static int ExposedC();
    // This is a public function. Your compiler should have no problem with other classes using it
    static int Internal() { return 0; }
};

然后,您为用户使用了不同的标题:

// UserB.h
// YouB.h
class B
{
public:
    static int ExposedA() { return 2 + A::Internal(); }
    static int ExposedB() { return 2; }
    static int ExposedC();
private:
    // This is a now a private or protected function.
    // I haven't tested this, so I don't know if the other access thing will work,
    // but since it's solely an internal function, commenting it out or removing
    // it completely should work too
    static int Internal() { return 0; }
};