我一直在阅读c++常见问题,对朋友声明很好奇。我个人从未使用过它,但我对探索这门语言很感兴趣。
使用friend的一个好例子是什么?
读了一些常见问题,我喜欢<< >>操作符重载和添加作为这些类的朋友的想法。然而,我不确定这如何不会破坏封装。什么时候这些异常可以保持在OOP的严格范围内?
我一直在阅读c++常见问题,对朋友声明很好奇。我个人从未使用过它,但我对探索这门语言很感兴趣。
使用friend的一个好例子是什么?
读了一些常见问题,我喜欢<< >>操作符重载和添加作为这些类的朋友的想法。然而,我不确定这如何不会破坏封装。什么时候这些异常可以保持在OOP的严格范围内?
当前回答
另一种用法:friend(+虚拟继承)可以用来避免从一个类派生(又名:“make a class underivable”)=> 1,2
从2:
class Fred;
class FredBase {
private:
friend class Fred;
FredBase() { }
};
class Fred : private virtual FredBase {
public:
...
};
其他回答
In C++ "friend" keyword is useful in Operator overloading and Making Bridge. 1.) Friend keyword in operator overloading :Example for operator overloading is: Let say we have a class "Point" that has two float variable"x"(for x-coordinate) and "y"(for y-coordinate). Now we have to overload "<<"(extraction operator) such that if we call "cout << pointobj" then it will print x and y coordinate (where pointobj is an object of class Point). To do this we have two option: 1.Overload "operator <<()" function in "ostream" class. 2.Overload "operator<<()" function in "Point" class. Now First option is not good because if we need to overload again this operator for some different class then we have to again make change in "ostream" class. That's why second is best option. Now compiler can call "operator <<()" function:
1.Using ostream object cout.As: cout.operator<<(Pointobj) (form ostream class).
2.Call without an object.As: operator<<(cout, Pointobj) (from Point class).
Beacause we have implemented overloading in Point class. So to call this function without an object we have to add"friend" keyword because we can call a friend function without an object. Now function declaration will be As: "friend ostream &operator<<(ostream &cout, Point &pointobj);" 2.) Friend keyword in making bridge : Suppose we have to make a function in which we have to access private member of two or more classes ( generally termed as "bridge" ) . How to do this: To access private member of a class it should be member of that class. Now to access private member of other class every class should declare that function as a friend function. For example : Suppose there are two class A and B. A function "funcBridge()" want to access private member of both classes. Then both class should declare "funcBridge()" as: friend return_type funcBridge(A &a_obj, B & b_obj);I think this would help to understand friend keyword.
典型的例子是重载操作符<<。另一个常见的用法是允许助手或管理类访问您的内部。
下面是我从c++朋友那里听到的一些指导原则。最后一个尤其令人难忘。
你的朋友不是你孩子的朋友。 你孩子的朋友并不是你的朋友。 只有朋友才能碰你的隐私部位。
在为类实现树算法时,教授给我们的框架代码将树类作为节点类的朋友。
它实际上没有任何好处,除了让你在不使用设置函数的情况下访问成员变量。
编辑:阅读faq有点长,我喜欢<< >>操作符重载和添加作为这些类的朋友的想法,但我不确定这如何不打破封装
它将如何破坏封装?
当允许对数据成员进行不受限制的访问时,就打破了封装。考虑以下类:
class c1 {
public:
int x;
};
class c2 {
public:
int foo();
private:
int x;
};
class c3 {
friend int foo();
private:
int x;
};
C1显然没有封装。任何人都可以读取和修改其中的x。我们没有办法实施任何形式的访问控制。
C2明显被封装了。没有对x的公共访问。你所能做的就是调用foo函数,它对类执行一些有意义的操作。
c3吗?它的封装程度低吗?它是否允许无限制地访问x?它是否允许未知函数访问?
不。它只允许一个函数访问类的私有成员。就像c2一样。就像c2一样,有访问权的函数不是“某个随机的未知函数”,而是“类定义中列出的函数”。就像c2一样,通过查看类定义,我们可以看到拥有访问权限的完整列表。
那么,这到底是如何减少封装的呢?同样数量的代码可以访问类的私有成员。类定义中列出了所有具有访问权限的人。
Friend不会破坏封装。这让一些Java程序员感到不舒服,因为当他们说“面向对象”时,他们实际上指的是“Java”。当他们说“封装”时,他们并不是说“必须保护私有成员不受任意访问”,而是说“在Java类中,唯一能够访问私有成员的函数是类成员”,尽管出于几个原因,这完全是无稽之谈。
首先,如上所述,它限制太大。没有理由不允许朋友方法做同样的事情。
第二,限制不够。考虑第四个类:
class c4 {
public:
int getx();
void setx(int x);
private:
int x;
};
根据上述Java思想,这是完美封装的。 但是,它允许任何人读取和修改x,这有什么意义呢?(提示:事实并非如此)
底线: 封装是关于能够控制哪些函数可以访问私有成员。这与这些函数的定义具体位于何处无关。
在构建容器并希望为该类实现迭代器时,Friend可以派上用场。