2011-05-01 88 views
1

我正准备回C++与我的一个朋友。我正在写一个基本的基于文​​本的地牢游戏,试图让玩家向上,下,左,右。那么我的问题有两个部分。我应该在这里使用朋友课吗?

我创建了一个地图类,一个Player类和GameLoop类。发生的一切显然都在我的GameLoop里面。 Map类有一个名为Move()的函数来移动播放器。在Map类中,我应该让我的Player类具有对Map类的友好访问吗?我对什么时候使用朋友类感到困惑。我想知道游戏循环函数是否应该使用map.Move(),或者如果我应该将Move()放入Player类中,使它们成为朋友并使用player.Move()。

我的地图级别保存坐标的私人数据,这是我的玩家定位的地方。

我知道这可能是有点主观的,但我有点一般说话。使用直接使用Map对象的效率更高的朋友类?

对我的第二个问题。我知道类很常见,但我想知道对象是否是。是否应该为每个类创建至少一个对象,或者甚至可以创建一个类并在不创建对象的情况下使用它?

+0

你为什么选择将'Move()'作为'Map'的成员函数,而不是'Player'? – Maxpm 2011-05-01 04:49:54

+0

@Maxpm:做这件事有很多原因,其中之一就是'Map'封装了玩家的位置。当您在2D网格上进行碰撞检测时,这非常有用。 – 2011-05-01 04:52:12

回答

2

类是有用的,因为他们可以有方法和状态/数据。一般来说,如果班级中有任何数据,那么您没有创建任何对象就没有意义。然而, 可以实现只有短短的公共静态功能的实用程序类。在这种情况下,您不必创建任何对象。

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; 
} 
+0

您可以创建一个类并在不“制作对象”的情况下使用它。这些被称为静态类,以防你想进一步研究它。 – Pete 2011-05-01 04:31:39

+0

我明白了。所以我通常应该只使用我创建的类的对象,即使在这个例子中,map.Move()比player.Move()更没有意义。我需要Move()来访问Map,因为玩家的坐标是Map的私人数据。并感谢您的答复。 – Christian 2011-05-01 04:36:18

+0

是的,请根据您的喜好使用对象,因为在您的情况下,我无法看到任何静态类。您可以将地图对象作为玩家状态的一部分,以便在玩家的移动()中可以访问坐标。再次,除了corrdinates之外,里面还有什么?如果没有别的,你可以将它移动到玩家类并摆脱地图... – 2011-05-01 04:39:55

0

至于你说的答案是主观的,我宁愿保持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; 

} 
+0

感谢您的回复。我使用Map是因为它将玩家的坐标保存在其私人数据中。 – Christian 2011-05-01 04:40:02

+0

@ vorbis5:您可以调用通过Map公开的公开方法,以更新移动细节的Map。 – 2011-05-01 04:43:52

2

作为friends是最紧密的耦合两个类可以具有。一般来说,您想要避免高耦合中隐含的依赖关系。你的Player类使用Map类的公共接口,除非你绝对使用friend

我会做这样的事情:

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

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

关于效率:friend并没有真正涉及到效率,因为公共/保护/私有检查是在编译时应用。即使这样做,使用friend来实现效率将是过早优化的一个明显例子 - 您应该避免。

如果你的类有一些或者只有静态成员,它可以在没有实例化对象的情况下使用。一个更常见的情况是你有一个类,但没有成员是抽象接口。这些类被设计为定义接口的基类,随后的类继承和实现。

+0

抽象类,是的,好点。 – 2011-05-01 04:46:58

+0

我不知道你可以传递一个函数作为参数。 – Christian 2011-05-02 00:15:28

+0

@ vorbis5:你可以传递函数指针,函子(在C++ 0x,lambdas中)。但是,在上面的代码中'input'应该是一个常规变量,'player.GetPosition()'不是函数,它是函数的返回值。 – Lstor 2011-05-02 11:30:43

0

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

我对什么时候使用朋友类感到困惑。

friend更像protectedpublic或在于它赋予局部选择性访问private。当您明确想要授予对单个类或函数的访问权限时,通常需要使用friend声明,而不是授予任何人访问权限。

你在一个摇滚和一个艰难的地方:你必须授予访问权限,所以你不能使用private;那么你再次必须封装你的数据,所以你不能使用public。在这些情况下,friendprotected可让您挤出紧张局势。

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

如果您想了解更多详细信息或示例,C++ FAQ有一个great section about friends

我知道这可能有点主观,但我有点谈论一般。使用直接使用Map对象的效率更高的朋友类?

这与主观无关。访问限制仅在编译期间使用,而不是在程序运行时使用。因此,它们不会导致运行时开销。如果所引用的数据成员是通过简单的内联getter函数来访问的,那么它也不应该导致开销。无论如何,我不会开始调查这个问题,我已经排除了其他一些案例,因为这可能是而不是你的瓶颈。

相关问题