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

时间:2011-05-01 04:14:28

标签: c++ class friend

我刚刚和我的一个朋友一起回到C ++。我正在写一个基于文本的基本地牢游戏,试图让玩家向上,向下,向左和向右移动。我的问题有两个部分。

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

我的地图类包含坐标的私人数据,这是我的玩家所在的位置。

我知道这可能有点主观,但我总体上说话。使用友元类比直接使用Map对象更有效吗?

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

4 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:2)

成为friends是两个类可以拥有的最紧密耦合。通常,您希望避免高耦合中隐含的依赖关系。让Player班级使用Map班级的公共界面,除非您绝对 使用friend

我会做这样的事情:

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

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

关于效率:friend与效率无关,因为公共/受保护/私有检查在编译时应用。即使这样做,使用friend来实现效率也会成为过早优化的明星例子 - 您应该避免这种情况。

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

答案 2 :(得分: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;

}

答案 3 :(得分:0)

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

  

我对何时使用朋友课感到困惑。

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

你处在困境中:你必须授予访问权限,因此你无法使用private;然后,必须封装您的数据,因此您无法使用public。在这些情况下,friendprotected可以让你挤出那个紧张的地方。

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

如果您需要更多详细信息或示例,C++ FAQ会有great section about friends

  

我知道这可能有点主观,但我总体上说话。使用友元类比直接使用Map对象更有效吗?

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