我一直在阅读c++常见问题,对朋友声明很好奇。我个人从未使用过它,但我对探索这门语言很感兴趣。

使用friend的一个好例子是什么?


读了一些常见问题,我喜欢<< >>操作符重载和添加作为这些类的朋友的想法。然而,我不确定这如何不会破坏封装。什么时候这些异常可以保持在OOP的严格范围内?


当前回答

在工作中,我们广泛地请朋友来测试代码。这意味着我们可以为主应用程序代码提供适当的封装和信息隐藏。但我们也可以有单独的测试代码,使用朋友来检查内部状态和数据进行测试。

可以说,我不会将friend关键字作为设计的重要组成部分。

其他回答

在做TDD的时候,我经常使用c++中的'friend'关键字。

朋友能知道我的一切吗?


更新:我从Bjarne Stroustrup网站上找到了这个关于“朋友”关键字的有价值的答案。

“好友”是一种授予访问权限的显式机制,就像会员资格一样。

安德鲁例子的另一个常见版本,可怕的密码对联

parent.addChild(child);
child.setParent(parent);

与其担心这两行是否总是一起执行,并且顺序一致,你可以将方法设为私有,并有一个friend函数来强制一致性:

class Parent;

class Object {
private:
    void setParent(Parent&);

    friend void addChild(Parent& parent, Object& child);
};

class Parent : public Object {
private:
     void addChild(Object& child);

     friend void addChild(Parent& parent, Object& child);
};

void addChild(Parent& parent, Object& child) {
    if( &parent == &child ){ 
        wetPants(); 
    }
    parent.addChild(child);
    child.setParent(parent);
}

换句话说,您可以保持公共接口更小,并强制在友元函数中跨越类和对象的不变量。

典型的例子是重载操作符<<。另一个常见的用法是允许助手或管理类访问您的内部。

下面是我从c++朋友那里听到的一些指导原则。最后一个尤其令人难忘。

你的朋友不是你孩子的朋友。 你孩子的朋友并不是你的朋友。 只有朋友才能碰你的隐私部位。

@roo:这里没有破坏封装,因为类本身规定了谁可以访问它的私有成员。只有当这可能是由类外部引起时,封装才会被破坏,例如,如果你的操作符<<声明“我是类foo的朋友”。

朋友代替了公开的用法,而不是私人的用法!

实际上,c++ FAQ已经回答了这个问题。

c++的创建者说这并没有破坏任何封装原则,我将引用他的话:

“朋友”是否违反封装? 不。但事实并非如此。“好友”是一种授予访问权限的显式机制,就像会员资格一样。你不能(在符合标准的程序中)在不修改类源的情况下授予自己对类的访问权。

很明显…