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

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


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


当前回答

树的例子是一个很好的例子: 在一些不同的类中实现一个对象 具有继承关系。

也许您还需要它具有一个构造函数protected和force 人们用你的“朋友”工厂。

... 好吧,坦白地说,没有它你也能生活。

其他回答

我发现了一个使用好友访问的方便地方:私有函数的Unittest。

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

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

很明显…

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

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);
}

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

树的例子是一个很好的例子: 在一些不同的类中实现一个对象 具有继承关系。

也许您还需要它具有一个构造函数protected和force 人们用你的“朋友”工厂。

... 好吧,坦白地说,没有它你也能生活。

简短的回答是:在friend确实可以改善封装时使用它。提高可读性和可用性(操作符<<和>>是典型的例子)也是一个很好的理由。

至于改进封装的例子,专门设计用于处理其他类的内部结构的类(想到了测试类)是很好的候选。