2014-01-08 109 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