我应该在这里使用朋友类吗?
我刚刚和我的一个朋友重新开始接触 C++。我正在编写一个基于文本的基本地下城游戏,试图让玩家向上、向下、向左和向右移动。嗯,我的问题有两个部分。
我创建了一个 Map 类、一个 Player 类和一个 GameLoop 类。发生的一切显然都在我的 GameLoop 中。 Map 类有一个名为 Move() 的函数来移动玩家。在 Map 类中,我应该让我的 Player 类对 Map 类有友谊访问权限吗?我对何时使用朋友类有点困惑。我想知道游戏循环函数是否应该使用map.Move(),或者我是否应该将Move()放入Player类中,使它们成为朋友,然后使用player.Move()。
我的地图类保存坐标的私有数据,这是我的玩家所在的位置。
我知道这可能有点主观,但我只是笼统地说。使用友元类是否比直接使用 Map 对象更有效?
关于我的第二个问题。我知道类很常见,但我想知道对象是否也很常见。是否应该为每个类至少创建一个对象,或者甚至可以创建一个类并在不创建对象的情况下使用它?
I'm just getting back into C++ with a friend of mine. I'm writing a basic text based dungeon game, trying to get the player to move up, down, left and right. Well my question has two parts.
I created a Map class, a Player class and a GameLoop class. Everything that happens is obviously going inside my GameLoop. The Map class has a function called Move() to move the player. In the Map class, should I let my Player class have friendship access to the Map class? I'm a little confused with when to use friend classes. I'm wondering whether the game loop function should use map.Move(), or if i should place Move() into the Player class, make them friends, and use player.Move().
My Map class holds the private data of the coordinates, which are where my player is positioned.
I know this might be a little subjective but I'm kinda talking in general. Is using a friend class more efficient then using the Map object directly?
On to my second question. I know that classes are very common, but I'm wondering if objects are. Should at least one object be created for every class, or could you even create a class and use it without making an object?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
类很有用,因为它们可以具有方法和状态/数据。一般来说,如果你的类中有任何数据,那么你不创建任何对象是没有意义的。然而,
您可以实现一个仅由公共静态函数组成的实用程序类。在这种情况下,您不必创建任何对象。
就您而言,没有必要使用静态类和我们所看到的朋友类。
对我来说,朋友类是我最后不会求助的东西。根据您的描述,您可以将
move()
设为player
类的公共方法,因为实际“移动”的是玩家而不是map.另外,您需要向我们明确您的
map
类的作用。编辑:如果您的地图类别足够简单,可以将玩家的坐标移动到玩家类别,则可以将其删除。
Classes are useful because they can have methods and state/data. Generally speaking, if there is any data in your class, it's meaningless that you don't create any objects. However,
you can implement a utility class which is composed of public static functions only. In such a case you don't have to create any object.
In your case, there is no need to use static class, and friend class as we can see.
To me, friend class is the last thing I'll resort to. According to your description, you can make
move()
be the public method ofplayer
class since it's the player who actually "moves" instead of themap
. Also, you need make it clear to us what's yourmap
class does.Edit: You can move coordinate of the player to player class if your map class is simpe enough to remove.
成为
朋友
是两个类之间最紧密的耦合。一般来说,您希望避免高耦合中隐含的依赖关系。让您的Player
类使用Map
类的公共接口,除非您绝对必须使用friend
。我会做这样的事情:
关于效率:
friend
并不真正与效率相关,因为公共/受保护/私有检查是在编译时应用的。即使确实如此,使用friend
来提高效率也将是过早优化的一个典型例子——您应该避免这种情况。如果您的类有一些或只有静态成员,则可以在不实例化对象的情况下使用它。更常见的情况是,您有一个类但没有成员,这是抽象接口。这些类被设计为定义接口的基类,随后的类将继承并实现该接口。
Being
friends
is the tightest coupling two classes can have. In general, you want to avoid the dependencies implied in high coupling. Have yourPlayer
class use the public interface of theMap
class, unless you absolutely have to usefriend
.I would do something like this:
Regarding efficiency:
friend
does not really relate to efficiency, since the public/protected/private checks are applied at compile-time. And even if it did, usingfriend
to achieve efficiency would be a star example of premature optimization -- which you should avoid.If your class has some or only static members, it could be used without instantiating an object. A more common case where you have a class but no members are abstract interfaces. These classes are designed to be base classes defining an interface, which later classes then inherit and implement.
正如您所说,答案是主观的,我更愿意将
Move()
保留在player
类中,因为它正在Player
上执行操作。我不确定 Map 类应该做什么。你没有提到这方面的细节。
您甚至可以创建一个类并在不创建对象的情况下使用它吗?
是的,可以有一个类并在类中具有静态方法,然后甚至可以在不创建该类的对象的情况下调用这些方法。但我想不出一个实际的例子。
代码示例:
As you said the answer is subjective, I would prefer keeping
Move()
insideplayer
class, as it is performing an action on thePlayer
.I am not sure of what
Map
class is supposed to do. You didn't mention a detail on that.Could you even create a class and use it without making an object?
Yes, It is possible to have a class and have static methods inside the class which can then be called without even creating an object of the class. I cannot think of an practical example though.
An code example:
我将对您问题的两个一般方面做出反应,并避免您所指的特殊情况。您没有提供太多细节,我希望一般情况能够帮助您决定是否需要使用友谊。
friend
比public
或private
更像是protected
,因为它授予 partial 或选择性访问。当您特别想要授予对单个类或函数的访问权限而不是向任何人授予访问权限时,通常需要使用friend
声明。您陷入了进退两难的境地:您必须授予访问权限,因此您无法使用
private
;然后,您必须封装您的数据,因此您不能使用public
。在这些情况下,friend
和protected
可以让您摆脱困境。friend
和protected
之间的基本区别在于,后者在您授予访问权限的实体数量方面是开放式。如果您需要更多详细信息或示例,C++ 常见问题解答有一个 关于朋友的精彩部分。
这与主观性无关。访问限制仅在编译期间使用,而不是在程序运行时使用。因此,它们不会产生运行时开销。如果通过简单的内联 getter 函数访问引用的数据成员,那么也不应该产生开销。无论如何,在排除了许多其他情况之前我不会开始调查这个问题,因为这可能不是您的瓶颈。
I'm going to react to the two general aspects of your question, and sort of avoid the special case you're referring to. You haven't provided much detail, and I hope the general case will help you decide whether you need use friendship or not.
friend
is more likeprotected
thanpublic
orprivate
in that it grants partial or selective access. You usually need to use afriend
declaration when you specifically want to grant access to a single class or function, rather than grant access to anybody.You're in a rock and a hard place: you must grant access, so you can't use
private
; then again you must encapsulate your data, so you can't usepublic
. In those cases,friend
andprotected
allow you to squeeze out of that tight spot.The basic difference between
friend
andprotected
is that the latter is open ended in the number of entities to whom you grant access.If you want more details or examples, the C++ FAQ has a great section about friends.
This has nothing to do with being subjective. Access restrictions are only used during compilation, not at program run-time. Therefore, they incur no runtime overhead. If the referred data member is accessed through a simple inlined getter function, then that shouldn't incur overhead either. In any case, I wouldn't start investigating this untlil I had ruled out a bunch of other cases, as this is likely not your bottleneck.