2014-01-08 104 views
0

我只是想問一個簡單的問題。一個指向二維數組對象類型指針的指針

我稱一類「ChessPiece」

#ifndef CHESSPIECE_H 
#define CHESSPIECE_H 

#include "Globals.h" 

// Abstract class for inheritence 
class ChessPiece { 
public: 
    // Constructor 
    ChessPiece(bool isWhite) : m_isWhite(isWhite) { 
    } 
    // No dynamic allocation 
    ~ChessPiece(void) {} 

    // pure virtual functions 
    virtual CellLocation *listAvailableMoves(void) = 0; 
    virtual char getPieceType(void) = 0; 
    virtual ChessPiece *clonePiece(void) = 0; 

    // ACCESSORS, MUTATORS 
    // isWhite member 
    bool isWhite(void) const{ 
     return m_isWhite; 
    } 

    void setIsWhite(bool isWhite) { 
     m_isWhite = isWhite; 
    } 

protected: 
    bool m_isWhite; 
}; 
#endif 

,我有這樣一個變量:

ChessPiece *m_gameBoard[8][8];

我想知道我怎麼可以定義一個指針,這個變量?我以爲它會像ChessPiece *(*pGameBoard)[8][8],但它不是我想要的。舉例說,我想打電話給這樣的*pGameBoard[2][2]->isWhite()(這不起作用)我該怎麼做?

在此先感謝您的答案。

+0

請參閱http://stackoverflow.com/questions/8617466/a-pointer-to-2d-array – IdeaHat

+0

你當然明白'm_gameBoard'是一個指針數組,而不是'ChessPiece'數組是的,是嗎? –

+0

是的,我知道它。棋子指針的二維數組。 –

回答

0

ChessPiece *(*pGameBoard)[8][8];做了指針聲明到m_gameBoard是在ChessPiece *m_gameBoard[8][8];類型。你將與​​使用它,例如:

(*pGameBoard)[2][2]->isWhite() 

然而,在大多數情況下,它是令人滿意的指向最外陣列而不是整個陣列的元件,如:

ChessPiece *(*pGameBoard)[8]; 

指向整個數組的指針和指向數組第一個元素的指針實際上是相同的地址。然而,因爲後者相當於前者已經應用的*操作,您可以使用這樣的:

pGameBoard[2][2]->isWhite() 

需要注意的是,與第一個聲明,你會分配或使用指針初始化整個陣列,與:

ChessPiece *(*pGameBoard)[8][8] = &m_gameBoard; 

同時,在後者的聲明,則將會分配或使用的指針數組的第一個元素,如對其進行初始化;

ChessPiece *(*pGameBoard)[8][8] = &m_gameBoard[0]; 

,或等效因爲縵陣列被自動轉換爲一個指向它的第一個元素,與:

ChessPiece *(*pGameBoard)[8][8] = m_gameBoard; 
+0

是的,你的答案解釋了很多。謝謝。我應該使用後者,因爲它會使我不使用解引用操作符嗎?解引用運算符(* asdf)是否意味着性能成本? –

+0

@JohnJohn:我期望沒有性能成本,因爲在這種情況下的解引用操作在編譯時是完全可解的,在任何正常的C++實現中都沒有運行時值的變化。 (它只是將類型從「指針指向數組」指向「指向元素的指針」,同時仍指向同一位置。)C++標準不要求**沒有性能成本,但是對於常規具有性能成本的現代架構質量非常差。大多數人使用後者是因爲它的「自然」外觀。 –

+0

再次感謝您的回答。 –

0
ChessPiece *m_gameBoard[8][8]; 

ChessPiece * (*pGameBoard)[8]; 
+0

所以.... pGameBoard是一個指向m_gameBoard數組的前8個元素的權利? –

+0

是的,你說得對。它是一個指向8個元素的指針數組的指針。這就是它指向原始數組中的第一行。 –

0

我不知道你是如何爲那些ChessPiece對象分配空間。無論我嘗試在堆棧上分配還是動態分配,我都會從g++得到編譯錯誤,因爲沒有默認構造函數。在堆棧中分配實例數組或使用new時,將爲每個創建的實例調用默認的構造函數。

在你ChessPiece類添加默認構造函數:

ChessPiece() : m_isWhite(false) {} 

然後你可以在棧上分配的數組:

ChessPiece pieces[8][8]; 

而且使用訪問數組:

pieces[i][j].isWhite(); 

這對我來說似乎更直接,讓我知道你的想法。

此外,您可能需要考慮使用代表Cell對象的網格的Board對象進行組織。每個Cell跟蹤它是否有一塊,如果有,可以返回該作品的參考/副本。對我而言,這在概念上更清晰,但你的方式也沒有錯。 :)

+0

那麼關鍵是要使用動態數組,以便它不會意味着堆大小的成本。我修改了代碼,以便「ChessPiece」現在只有2個字節,而指向它的指針將是4個字節。就您的方法而言,我們都在董事會代表性背後使用同樣的想法,名稱並不重要。唯一的另一種選擇是不存儲棋盤,而是存儲自己位置的棋子。但是,在搜索某個位置時,這會產生一些性能成本,因此我選擇了這種方式。感謝您的關注。 –

+0

我不明白你的意思..按照定義動態分配佔用堆空間。在這一點上,你應該專注於讓程序正常工作。過早優化是萬惡之源!我真的不會擔心它的兩個或四個字節,還是關於堆的成本。除非你使用的是幾十年前的計算機,否則內存應該足夠用於棋盤。 – Keeler

+0

片段搜索結果中有多少性能影響?你可以做一個線性搜索,它在64個項目的數組中將不會花費時間。 – Keeler