我应该在这里使用朋友类吗?

发布于 2024-11-04 11:30:32 字数 499 浏览 3 评论 0原文

我刚刚和我的一个朋友重新开始接触 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

时光病人 2024-11-11 11:30:32

类很有用,因为它们可以具有方法和状态/数据。一般来说,如果你的类中有任何数据,那么你不创建任何对象是没有意义的。然而,
您可以实现一个仅由公共静态函数组成的实用程序类。在这种情况下,您不必创建任何对象。

Class CMyHelper
{
public:
    static double calculateDistance(CPoint A, CPoint B);
    static double calculateArea(double length, double width);
    //...
private:
    // You can even explictly say, I don't want make objects of this class.
    // You'll get a compile-time error if someone tries.
    CMyHelper();
    CMyHelper(const CMyHelper&);
}

CPoint A(100, 200);
CPoint B(50, 100);
//Call static method without instantiation
CMyHelper::calculateDistance(A, B);

就您而言,没有必要使用静态类和我们所看到的朋友类。

对我来说,朋友类是我最后不会求助的东西。根据您的描述,您可以将 move() 设为 player 类的公共方法,因为实际“移动”的是玩家而不是 map.另外,您需要向我们明确您的 map 类的作用。

编辑:如果您的地图类别足够简单,可以将玩家的坐标移动到玩家类别,则可以将其删除。

Class CPlayer
{
public:
    void move()
    {
        // moves up, down, left, or right
        // update m_position
    }
}

private:
    CCoordinate m_position;
}

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.

Class CMyHelper
{
public:
    static double calculateDistance(CPoint A, CPoint B);
    static double calculateArea(double length, double width);
    //...
private:
    // You can even explictly say, I don't want make objects of this class.
    // You'll get a compile-time error if someone tries.
    CMyHelper();
    CMyHelper(const CMyHelper&);
}

CPoint A(100, 200);
CPoint B(50, 100);
//Call static method without instantiation
CMyHelper::calculateDistance(A, B);

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 of player class since it's the player who actually "moves" instead of the map. Also, you need make it clear to us what's your map class does.

Edit: You can move coordinate of the player to player class if your map class is simpe enough to remove.

Class CPlayer
{
public:
    void move()
    {
        // moves up, down, left, or right
        // update m_position
    }
}

private:
    CCoordinate m_position;
}
孤凫 2024-11-11 11:30:32

成为朋友是两个类之间最紧密的耦合。一般来说,您希望避免高耦合中隐含的依赖关系。让您的 Player 类使用 Map 类的公共接口,除非您绝对必须使用friend

我会做这样的事情:

void MainLoop() {
    // ... Read input and so on ...

    player.Move(input);
    map.Update(player.GetPosition());
}

关于效率: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 your Player class use the public interface of the Map class, unless you absolutely have to use friend.

I would do something like this:

void MainLoop() {
    // ... Read input and so on ...

    player.Move(input);
    map.Update(player.GetPosition());
}

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, using friend 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.

蓝颜夕 2024-11-11 11:30:32

正如您所说,答案是主观的,我更愿意将 Move() 保留在 player 类中,因为它正在 Player 上执行操作。

我不确定 Map 类应该做什么。你没有提到这方面的细节。

您甚至可以创建一个类并在不创建对象的情况下使用它吗?
是的,可以有一个类并在类中具有静态方法,然后甚至可以在不创建该类的对象的情况下调用这些方法。但我想不出一个实际的例子。

代码示例:

class MyClass
{
    static int i;

    public:
    static void incrementCount()
    {
         i++;
    }

    static int returnCount()
    {
         return i;
    }
};

int MyClass::i = 0;

int main()
{

    int count;
    //Do Some processing

    MyClass::incrementCount();

    //Do Some More processing

    count = MyClass::returnCount();        

    return 0;

}

As you said the answer is subjective, I would prefer keeping Move() inside player class, as it is performing an action on the Player.

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:

class MyClass
{
    static int i;

    public:
    static void incrementCount()
    {
         i++;
    }

    static int returnCount()
    {
         return i;
    }
};

int MyClass::i = 0;

int main()
{

    int count;
    //Do Some processing

    MyClass::incrementCount();

    //Do Some More processing

    count = MyClass::returnCount();        

    return 0;

}
靑春怀旧 2024-11-11 11:30:32

我将对您问题的两个一般方面做出反应,并避免您所指的特殊情况。您没有提供太多细节,我希望一般情况能够帮助您决定是否需要使用友谊。

我对何时使用友元类有点困惑。

friendpublicprivate 更像是 protected,因为它授予 partial选择性访问。当您特别想要授予对单个类或函数的访问权限而不是向任何人授予访问权限时,通常需要使用 friend 声明。

您陷入了进退两难的境地:您必须授予访问权限,因此您无法使用private;然后,您必须封装您的数据,因此您不能使用public。在这些情况下,friendprotected 可以让您摆脱困境。

friendprotected 之间的基本区别在于,后者在您授予访问权限的实体数量方面是开放式

如果您需要更多详细信息或示例,C++ 常见问题解答有一个 关于朋友的精彩部分

我知道这可能有点主观,但我只是笼统地说一下。使用友元类比直接使用 Map 对象更高效吗?

这与主观性无关。访问限制仅在编译期间使用,而不是在程序运行时使用。因此,它们不会产生运行时开销。如果通过简单的内联 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.

I'm a little confused with when to use friend classes.

friend is more like protected than public or private in that it grants partial or selective access. You usually need to use a friend 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 use public. In those cases, friend and protected allow you to squeeze out of that tight spot.

The basic difference between friend and protected 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.

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?

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文