c++ 友元 friend的好处是?
友元函数,或者友元类,可以访问一个类的private成员。
可以偷懒
[解决办法]
比如一个管理对象Manager,和一个被管理单元Item。
二者之间没有继承关系,但Manager需要管理Item,需要访问Item的所有成员,你就自然而然想到友元。
当然更多的例子是操作符重载。
[解决办法]
友元只对特定目标开放,而public对所有目标开放,两者作用不同,不可相互替代。你举的这个例子是不对的。只允许部分类或函数访问自己的私有成员,其它人不行,这件事非友元不能做。
友元并没有破坏封装。将何人设成友元,或者说允许谁来访问本类的私有成员,完全是由本类的作者决定的,如同将哪些成员设成公共成员一样。public控制开放哪些成员,friend控制开放的目标,是控制的两种表现形式,并不是对立的,所以从概念上讲并没有破坏封装。
所谓“封装”,并不是说把所有的东西都包起来不给别人看,而是指有控制的允许一些人看到一些东西,强调的是“控制”,而不是“隐藏”。有“隐藏”必有“开放”,否则就谈不上封装了,关键在于作者能不能控制这种开放。有的语言不能控制,就说它不具有“封装”特性,有的语言能够控制,就说它具有“封装”特性。
C++的“封装”特性是指其能够“控制开放”,友元只是细化这种控制,并没有失去控制,所以并没有破坏“封装”。类似还有protected,只允许特定目标访问特定成员,也是对“封装”的细化,都在类的作者的控制之下。
最初曾考虑过将friend进一步细化到控制单独的成员,也就是说同时控制开放成员与目标,不过语法上太别扭了,所以现在friend作用于所有成员,public作用于所有目标。
------解决方案--------------------
存在即合理吧
[解决办法]
10分......
[解决办法]
如果你只允许某个人进入你的卧室,他就是你的friend

[解决办法]
我也感觉不用友元也一样实现功能
[解决办法]
少用, 有时为了方便使用下友元, 但不是必须的。
[解决办法]
直接访问类的私有数据
[解决办法]
加法就必须用友元吧,以前的哪本书讲过,primer还是effective c++?
[解决办法]
支持2楼和7楼
[解决办法]
"这是 友元的 一般功能。但是这个也可以通过其他方式实现啊。
比如在func里面通过B类的public接口修改data:" 如果只希望某个特定的类的对象,能够改写你的私有成员,其它类不能改。。。
[解决办法]
在线程里通过友元访问类的私有成员感觉挺好用的, 要不就得定义全局变量了。
[解决办法]
为什么房子要装防盗门锁,再配钥匙呢?为什么进门拿钥匙开锁进去呢?
可以用其他的设计方法也可以进房子啊,比如直接不装锁,或者不装门,那不是更方便出入吗?
装锁的问题就在于只想让有钥匙的人进来,而阻挡其他人进来。
友员也是这样。
[解决办法]
友元本来就破坏了封装性。
友元的作用,只是让非派生类或者函数能使用该类的方法。
就像继承跟聚合一样,继承的耦合太大,而偏向采用聚合。
[解决办法]
这样的例子很多了。
比如Unix下的权限,有用户自己的权限,组用户权限,其他用户权限。
QQ空间的可以设置开放的,或者仅好友才能查看。
[解决办法]
没有什么是非友元实现不了的,就好像没有什么是非C++实现不了的。
[解决办法]
8#说的很清楚了,只让部分函数或类访问本类的私有数据,非友员不能做。
[解决办法]
没看别人的回复,就说我用到的地方吧.
不知道你有没有看过设计模式这样的书,比如要写一些算法,这些算法的基本骨架一样,可以把这些算法里可以合并(复用)的单元,写成一些类,而这些类单独在外面用,是没法用的,但避免不了用户看到这个类后,自己用.那就把这些个单元类全部的函数都私有化.而把那个算法骨架设为这些类的友元类,这样就只有这个算法骨架类可以利用这些算法单元.
[解决办法]
8楼的知识点基本上都所错误的。
[解决办法]
友元只对特定目标开放,而public对所有目标开放,两者作用不同,不可相互替代。你举的这个例子是不对的。只允许部分类或函数访问自己的私有成员,其它人不行,这件事非友元不能做。
友元并没有破坏封装。将何人设成友元,或者说允许谁来访问本类的私有成员,完全是由本类的作者决定的,如同将哪些成员设成公共成员一样。public控制开放哪些成员,friend控制开放的目标,是控制的两种表现形式,并不是对立的,所以从概念上讲并没有破坏封装。
我第一次听说友元没有破坏封装。不管是面向过程还是面向对象编程,都讲的是数据隐藏;封装是为了数据隐藏,既然友元函数/对象都能毫无限制的访问所有成员,封装已不受控制,还没有破坏封装?
所谓“封装”,并不是说把所有的东西都包起来不给别人看,而是指有控制的允许一些人看到一些东西,强调的是“控制”,而不是“隐藏”。有“隐藏”必有“开放”,否则就谈不上封装了,关键在于作者能不能控制这种开放。有的语言不能控制,就说它不具有“封装”特性,有的语言能够控制,就说它具有“封装”特性。
只要你定义了public接口,你无法控制你的类被谁使用。你怎么控制你的对象之被某些人调用? 你只能控制你的某个接口是public,所以所有的编程还是讲的隐藏。一个类的作者只能控制这种开放而不是谁能调用你的类。如果你实在要争执,去买 <<code complete II>>来读读。
C++的“封装”特性是指其能够“控制开放”,友元只是细化这种控制,并没有失去控制,所以并没有破坏“封装”。类似还有protected,只允许特定目标访问特定成员,也是对“封装”的细化,都在类的作者的控制之下。
基本的封装概念没有理解,在作者的控制之下就能够说一个类的封装没有被破坏? 类的封装是指作者的控制权?
最初曾考虑过将friend进一步细化到控制单独的成员,也就是说同时控制开放成员与目标,不过语法上太别扭了,所以现在friend作用于所有成员,public作用于所有目标。
就这种编程能力,你还是全部public得了。
[解决办法]
举个例子,有一个工厂类叫CFactory,它有一个接口 IObject CreateObject(); CObject, CObject2等继承自IObject。
CreateObject() 为了向调用者隐藏具体的IObject实现类,并且要求调用者不能私自创建IObject的具体类对象。 一句话,我们想只对CFactory开放,IObject具体类对象的创建。所以我们把各IObject具体类的构造函数声明为私有,向CFactory声明为friend。
[解决办法]
说得太好了!
[解决办法]
Bjarne Stroustrup 《C++语言的设计与演化》(中文版)第46页:
访问权的授予方式就是把一个成员的声明放在类声明的公用部分,或是把某个特定函数或者类声明为一个friend。
友元关系被看成一种机制,类似于一个保护域将读写的权力授与另一个,这需要在类声明中明显写出,而且是特指的。因此我从来都不能认同反复出现的friend声明“侵犯了封装机制”的断言,它们不过是用非C++术语表达的无知和混乱。
第48页:
多年来也出现了许多建议,希望能提供对小于整个类的单元的保护,例如:
grant X::f(int) access to Y::a, Y::b, and Y::g(char);
我一直在抗拒这类建议。我的基本想法是这种小粒度控制不会增加任何保护……由更多显式控制得到的利益抵不上它所带来的在描述、实现和使用方面的复杂性。
[解决办法]
从BS的说法可以看出,C++的封装机制从一开始就是由private、public和friend共同组成的,其中public和friend分别用于不同方式的控制开放,friend并不是为了破坏封装而打的补丁。
protected倒是后来版本才加进来的。注意protected同时控制开放内容和开放目标,兼有public和friend的特征。如果承认protected是封装机制的一部分,那么就要承认对开放目标的控制是封装机制的一部分,自然专门控制开放目标的friend也是封装机制的一部分。
据BS说,因为他以前从事过操作系统的开发,所以从操作系统(而不是从其它编程语言)那里借鉴证了“保护概念”。具体地说就是访问权的授予,这个思想后来才被总结为面向对象的封装机制。“授予访问权”也就是我前面说的“控制开放”,这才是封装机制的核心。所以,封装机制强调的是“控制”,而不是“隐藏”
[解决办法]
即使单独把BS的语言翻出来作为引用,那么你的表达还是有错误的. 毫无上下文的表达是很苍白和容易被误解的。比如下面一个问题:
class A 和 class B是两个独立的类,Class B希望能够获取Class A 的其中一个成员,把class B申明为class A的友元,是不是破坏封装?
正确的说法是“合理的使用friend”不仅没有破坏封装,而且还帮助封装.
上面的例子使用了友元就是破坏了封装了,因为A/B根本没有什么关系,将友元授予了B就是破坏了封装。
那么什么情况下友元又是帮助封装呢?
比如有A和B本来属于一个类,或者A/B具有非常高的耦合,A没有B无法提供功能,B没有A功能不全,那么这个时候使用友元就是提升了封装。因为有了友元A/B类各自有了更好的封装,各自的职责更清晰,但是又互相支持。如果不把A/B分开成两个类,那么原来的类变得臃肿。
[解决办法]
“封装”是指C++语言(或是广泛地说面向对象语言)的封装机制,不是从字面意义上理解的“封起来“。封装机制的要点是控制开放,或者说授予访问权,详细地说,就是决定哪些人能看到哪些内容。“隐藏”与“开放”是对立统一的,在决定“隐藏”什么同时,就决定了要“开放”什么。把“封装机制”说成是“开放机制”也无不可,意思一样,就看当初命名时用哪个词顺口。
控制开放的方式,既可先划定一个大范围的开放,再决定其中哪些隐藏,也可以先划定一个大范围的隐藏,再决定其中哪些开放。前者的例子是struct,后者的例子是class。这是因为要兼容C的用法,并不是必须要这样做。这是控制开放成员的情况。
控制开放目标的情况只设计了缺省隐藏后用friend显示开放,从表面上看,像是在“开放”,不像是在“隐藏”。假如说换一个关键字secret,控制哪些类或函数不可访问本类的公有成员,这看上去就更像是在“隐藏”了,其实在控制机制上与friend没什么区别,只是语法细节不同。
总之,封装的目的就是要控制哪些人可以访问哪些内容,通过private,public和friend的组合来实现。friend是封装机制的一部分,怎么能说是破坏封装呢?能说private是破坏开放机制吗?
我不觉得“合理的使用friend”与“使用friend“的结论有什么文字游戏以外意义上的不同,这里的一切讨论当然是指合理的使用。由于”不合理的使用“造成的”破坏XX“的情况,对于一切语言机制都适用,这是使用者的问题,不是语言的问题。“不合理的使用指针”会造成系统崩溃,能说C++的指针机制造成系统崩溃吗?
你举的例子,如果class A不想让class B以外的类访问,那只能加B为友元。“封装”就是用来控制访问权的,class B想访问class A的成员,怎么能说A/B根本没什么关系呢?
你的第二个例子,只是两个类相互访问,又不想被第三者插足,不过是friend的一个特殊应用而已。
[解决办法]
某些运算符重载不用friend根本没法实现吧,比如<<
[解决办法]
还有就是
在运算时,有数和对象的混合运算时,运算符重载最好使用友元
[解决办法]
不一定必须是友元,但是友元好些
因为1+a 私有会报错 只能是a+1 或者b+a,a+b
而友元不会
[解决办法]
友元机制是为了对部分用户开后门,如果换成public后就变成完全开放,完全没有限制。
典型场景:运算重载。
[解决办法]
成员函数要求是有对象调用,则第一个参数必须是类的对象,但是<<和>>第一个参数是流的对象引用。
故,不能使用成员函数。
如果你认为<<cout和>>cin也可以的话,那我觉得ok的。