何时在 C++ 中使用友元类
可能的重复:
什么时候应该在 C++ 中使用“friend”?
我正在复习在我的 C++ 中(我是一名 Java 开发人员),我遇到了我已经忘记了一段时间的 friend class
关键字。 这是厨房水槽的一部分功能之一,还是有充分的理由这样做,而不仅仅是一个普通的吸气剂? 我理解其中的区别,因为它限制了谁可以访问数据,但我想不出有必要这样做的场景。
注意:我见过类似的问题,但我具体要问的是,这只是一个高级功能,除了让人们在看你的代码时感到困惑直到他们意识到你在做什么之外,没有任何实际价值吗?
Possible Duplicate:
When should you use 'friend' in C++?
I was brushing up on my C++ (I'm a Java developer) and I came across the friend class
keyword which I had forgotten about for a while. Is this one of those features that's just part of the kitchen sink, or is there a good reason for doing this rather than just a vanilla getter? I understand the difference in that it limits who can access the data, but I can't think of a scenario when this would be necessary.
Note: I've seen a similar question, but specifically I'm asking, is this just an advanced feature that adds no real value except to confuse people looking at you're code until they realize what you're doing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
我同意这样的评论:如果使用得当,friend 关键字可以改善封装。 我只是补充一点,友元类最常见(合法!)的用途可能是测试。 您可能希望测试人员类比其他客户端类具有更大程度的访问权限。 测试人员类可能有充分的理由查看故意对其他类隐藏的内部细节。
I agree with the comments that say the friend keyword can improve encapsulation if used wisely. I'd just add that the most common (legitimate!) use for friend classes may be testing. You may want a tester class to have a greater degree of access than other client classes would have. A tester class could have a good reason to look at internal details that are deliberately hidden from other classes.
根据我的经验,与使用友元(或可变,有点相似)来实际增强数据封装的情况相比,它用于破坏封装的情况很少见。
它对我来说很少有用,但是当我使用它时,它是在我必须将以前是单个类的类拆分为两个需要访问一些公共数据/功能的单独类的情况下。
编辑回应Outlaw Programmer的评论:我们绝对同意这一点。 除了拆分类后将类交友之外,另一种选择是创建公共访问器,这有时会破坏封装! 我认为有些人认为友好的类在某种程度上破坏了封装,因为他们经常看到它被错误地使用,并且许多人可能从未见过它被正确使用的代码,因为这是一种罕见的事情。 不过,我喜欢你的表述方式——友好是一个很好的中间立场,介于不允许你分裂你的班级和让一切都向公众开放之间。
编辑回应 David Thornley:我同意 C++ 允许你做这样的事情的灵活性是 C++ 设计决策的结果。 我认为这使得了解灵活语言中通常好的和坏的风格变得更加重要。 Java 的观点是,您永远不应该拥有友元类,因此不会提供这些友元类,但作为 C++ 程序员,我们作为社区有责任定义这些非常灵活但有时被误用的语言结构的适当使用。
编辑回应 Tom: Mutable 并不一定会破坏封装,但是我在现实生活中看到的 mutable 关键字的许多使用都破坏了封装,因为看到人们用 mutable 破坏封装比使用 mutable 破坏封装更常见实际上首先找到并理解 mutable 的正确用法。
In my experience, the cases when friend (or mutable, which is a little similar) to actually enhance encapsulation of data are rare compared with how often it's used to break encapsulation.
It's rarely useful to me but when I do use it it's for cases in which I've had to split a class that was formerly a single class into two separate classes that need to access some common data/functionality.
Edit to respond to Outlaw Programmer's comment: We absolutely agree on this. One other option apart from friend'ing classes after splitting them is to make public accessors, which sometimes break encapsulation! I think that some people think that friendly classes somehow breaks encapsulation because they've seen it used improperly a lot, and many people probably never see code where it's been used correctly, because it's a rare thing. I like your way of stating it though - friendliness is a good middle ground between not allowing you to split up your class and making EVERYTHING accessible to the public.
Edit to respond to David Thornley: I agree that the flexibility that C++ allows you to do things like this is a result of the design decisions that went into C++. I think that's what it makes it even more important to understand what things are generally good and bad style in flexible languages. Java's perspective is that you should never have friend classes so that these aren't provided, but as C++ programmers it's our responsibility as a community to define appropriate use of these very flexible but sometimes misused language constructs.
Edit to respond to Tom: Mutable doesn't necessarily break encapsulation, but many of the uses of the mutable keyword that I've seen in real-life situations break encapsulation, because it's much more common to see people breaking encapsulation with mutable than to actually find and understand a proper use of mutable in the first place.
当您希望一个类(Factory)负责创建另一类(Type)的实例时。 您可以将 Type 的构造函数设为私有,从而确保只有 Factory 可以创建 Type 对象。 当您希望将检查委托给可以充当验证器的其他类时,它非常有用。
只是一种使用场景。
PS 确实缺少 C# 中的“friend”关键字...
When you wish that one class (Factory) be responsible for creating instances of another class (Type). You can make the constructor of the Type private and thus make sure that only the Factory can create Type objects. It is useful when you wish to delegate the checks to some other class which could serve as a validator.
Just one usage scenario.
P.S. Really missing the "friend" keyword in C#...
一个具体的实例是类工厂,您希望一个类只能通过另一个工厂类创建,因此您将构造函数设为私有,并将工厂类设为生成类的友元。
它有点像 2 英寸 12 点 3/4 英寸驱动套筒 - 不太常见,但当您需要它时,您会非常高兴拥有它。
A concrete instance would be a class factory, where you want one class to only be created through another factory class, so you make the constructors private, and the factory class a friend of the produced class.
It's kinda' like a 2" 12-point 3/4"-drive socket - not terribly common, but when you need it, you're awfully glad you have it.
有助于Memento 设计模式
Helps with Memento design pattern
关于好友的常见问题解答部分:此处
关于好友的常见问题解答部分:< a href="http://yosefk.com/c++fqa/fqa.html#fqa-friend" rel="nofollow noreferrer">此处
关于朋友的两种不同观点。
The FAQ's section about friends: here
The FQA's section about friends: here
Two different points of view about friend.
我将
friend
结构视为应该在极少数情况下使用的语言功能之一,但这并不意味着它毫无用处。 有几种模式需要创建friend
类,其中许多已经位于此站点右侧的“相关”栏中。 ====>I look at the
friend
construct as one of those features of the language that should be used in rare occasions, but that doesn't make it useless. There are several patterns that call for makingfriend
classes, many of them already on this site in that "Related" bar on the right. ====>当您有多个类和/或函数一起工作以提供相同的抽象或接口时,就会使用友谊。 典型的例子是实现某种数值类,所有非成员运算符函数(*、-、+、<<等)都被赋予友谊,以便它们可以处理数值类的私有数据。
这样的用例有点罕见,但确实存在,而且朋友非常有用。
Friendship is used when you have multiple classes and/or functions that work together to provide the same abstraction or interface. The classic example is implementing some kind of numerical class, and all the non-member operator functions (*, -, +, <<, etc) are given friendship so that they can work on the private data of the numerical class.
Such use cases are somewhat rare, but they do exist, and friend is very useful.
我确信,这是几个示例中的一个,其中可以合法地使用友元类,而无需忽略封装的原因。
MyClass继承自GeneralClass。 MyClass已经变大了,所以你创建了HelperClass来封装MyClass的一些功能。 然而,HelperClass 需要访问 GeneralClass 中的一些受保护函数才能正确执行其功能,因此您使 HelperClass 成为 MyClass 的友元。
这比公开受保护的函数要好,因为它们不需要对每个人都可用,但它有助于以 OOP 方式组织代码,以防止 MyClass 变得过于复杂。 这是有道理的,因为虽然 HelperClass 并没有通过继承与 MyClass 具体相关,但它确实与 MyClass 有某种逻辑联系,体现在代码和设计中,作为“朋友”。
Here is one example, of several, I'm sure, where a friend class can be legitimately used without disregarding the reasons for encapsulation.
MyClass inherits from GeneralClass. MyClass has gotten big, so you created HelperClass to encapsulate some of the function of MyClass. However, HelperClass needs access to some protected functions in GeneralClass to properly perform it's function, so you make HelperClass a friend to MyClass.
This is better than exposing the protected functions, because they don't need to be available to everybody, but it helps keep your code organized in an OOP way to keep MyClass from getting too complex. It makes sense, because although HelperClass isn't concretely related to MyClass by inheritance, it does have some sort of logical connection to it, embodied in the code, and in design, as "friend".
我总是(并且只)使用朋友来对私有方法进行单元测试。 我可以想象做到这一点的唯一其他方法是使用大量测试方法加载公共接口,这太混乱了,所以我更喜欢将测试方法隐藏在单独的测试类中。
像这样的事情:
I always ( and only ) use friend for unit testing private methods. The only other way I can imagine to do this would be to load up the public interface with a whole lot of testing methods, which is just too messy and so I prefer to hide the test methods in a seperate test class.
Something like this:
友元类意味着我们都知道它是从其他类访问变量的值,因此它主要用于使用这些值,因此我们不需要将其他类的值返回到主函数,然后返回到所需的类成员函数,但它具有问题是一个类是其他类的朋友,那么朋友类应该位于该类的下面
friend class mean we all know that is acesss the value of variable from other class so it is mainly used for use the values so we no need to return the value of other class to main function then main to needed class member function but it having the problem that is a class is friend for other class then friend class should be in below of that class