2011-05-01 61 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函數來訪問的,那麼它也不應該導致開銷。無論如何,我不會開始調查這個問題,我已經排除了其他一些案例,因爲這可能是而不是你的瓶頸。

相關問題