析构函数和指向类属性的指针
Destructors and pointers to class attributes
我有一个类ChessBoard,这是它的头文件:
class ChessBoard
{
Field** board;
Color currentColor;
public:
ChessBoard();
ChessBoard(const ChessBoard&);
Field* findField(std::string);
ChessBoard& operator = (const ChessBoard&);
bool checkIfFieldHasFigure(std::string);
void writeOneState(SahApi*);
void playAllMoves(std::istream*, SahApi*);
void playMove(std::string);
~ChessBoard();
};
我有它的构造函数,它创建了棋盘的开始阶段:(很难看,我知道:))
ChessBoard::ChessBoard()
{
int i, j;
Error err;
board = new Field*[8];
if(!board)
{
err.writeToOutput(1);
exit(1);
}
for(i = 0; i < 8; i++)
{
board[i] = new Field[8];
if(!board[i])
{
err.writeToOutput(1);
exit(1);
}
}
currentColor = WHITE;
char c;
std::string s;
Figure f;
for(i = 0; i < 8; i++)
for(j = 0; j < 8; j++)
{
s.clear();
c = i + 'A';
s.push_back(c);
c = j + '1';
s.push_back(c);
board[i][j].position.assign(s);
if((j > 1) && (j < 6))
board[i][j].hasFigure = 0;
else board[i][j].hasFigure = 1;
if((i+j+2) % 2)
board[i][j].color = WHITE;
else board[i][j].color = BLACK;
if( ((j==0)||(j==7)) && ((i==0)||(i==7)) )
{
Rook* r = new Rook(((j==0)?WHITE:BLACK), s);
if(!r)
{
err.writeToOutput(1);
exit(1);
}
board[i][j].putFigure(r);
}
else if( ((i==1)||(i==6)) && ((j==0)||(j==7)) )
{
Knight* n = new Knight(((j==0)?WHITE:BLACK), s);
if(!n)
{
err.writeToOutput(1);
exit(1);
}
board[i][j].putFigure(n);
}
else if( ((i==2)||(i==5)) && ((j==0)||(j==7)) )
{
Bishop* b = new Bishop(((j==0)?WHITE:BLACK), s);
if(!b)
{
err.writeToOutput(1);
exit(1);
}
board[i][j].putFigure(b);
}
else if( (i==3) && ((j==0)||(j==7)))
{
Queen* q = new Queen(((j==0)?WHITE:BLACK), s);
if(!q)
{
err.writeToOutput(1);
exit(1);
}
board[i][j].putFigure(q);
}
else if( (i==4) && ((j==0)||(j==7)) )
{
King* k = new King(((j==0)?WHITE:BLACK), s);
if(!k)
{
err.writeToOutput(1);
exit(1);
}
board[i][j].putFigure(k);
}
else if( (j==1) || (j==6) )
{
Pawn* p = new Pawn(((j==1)?WHITE:BLACK), s);
if(!p)
{
err.writeToOutput(1);
exit(1);
}
board[i][j].putFigure(p);
}
}
}
我还需要为棋盘设置一个析构函数,就像这样:
ChessBoard::~ChessBoard()
{
//for(int i = 0; i < 8; i++)
// delete board[i];
delete [] board;
}
被注释掉的原因是我的第一个问题:
1。为什么我不能用上面写的方法删除我所有的字段?当我尝试这样做时,程序进入"块类型是有效的"错误,我知道这是由于试图删除不存在的内存引起的。当我把它注释掉时,程序运行得很好。棋盘是一个8x8的矩阵,所以我应该可以像这里一样删除它。
第二个问题是:
2。我如何删除指针的数字(国王,王后,车,…)存在于我的构造器象棋棋盘?这是令人困惑的,因为这些指针被用作我的象棋棋盘的一部分,我一直使用它们直到程序结束。当程序结束时,我需要释放内存,但我不知道如何访问这些指针。图本身被自动删除,因为它们都是非指针。我是否甚至需要删除那些指针,因为我使用它们直到结束,然后所有内容都被释放?
-
new/delete的一般规则是调用必须相互匹配。你用
创建你的板board = new Field*[8]; for(i = 0; i < 8; i++) { board[i] = new Field[8]; }
您将需要以相同的方式删除您的板,但向后:
for(i = 0; i < 8; i++) { delete [] board[i]; } delete[] board;
既然这是不工作,我猜你的问题是双重删除。其他东西正在释放数组。是否有可能你有一个副本的棋盘,是指向相同的领域**?
-
你必须用同样的方法删除你的数字。
for (int x = 0; x < 8; x ++) for (int y = 0; y < 8 ;y ++) if (board[y][x] != NULL) delete board[y][x];
只要你从棋盘上删除一个数字的代码删除了该数字并将该数字的位置设置为NULL,该代码就可以工作。
2 b。你问题的第二部分是你是否需要做这些删除,因为程序要结束了。你是对的,因为你不需要删除任何东西,如果你打算马上退出,操作系统会为你释放所有的内存。
你通常应该这样做,通常你最终会修改大多数程序,允许它们运行多次,然后你的将有内存泄漏,因为每次运行会使用更多的内存。
这就是如何解决你的问题。但是,我强烈建议您更改大部分代码的风格,并删除所有的动态分配。
首先,使用一个常规的静态大小的数组(Field[8][8])来存储字段。我是说,象棋场什么时候会改变大小?
第二,按值存储片段。您的字段类已经存储了某个部件是否位于某个位置。还要让Field类存储一个表示类型的enum。没有理由为您的片段使用动态分配。
第三,不需要检查new
的返回是否为NULL。如果有一个错误,它将抛出一个异常,并且您的程序将停止(正如它应该的那样,当内存不足时,您可以做的事情不多)。
- 通过指向指针数组的指针访问子类的属性
- 重新检查时指针属性会更改
- 返回的指针属性中类实例上的矢量属性消失
- boost::spirit指针属性是用nullptr初始化的吗?
- 如何使用指针从另一个类访问属性
- 我想获取点的属性,它报告错误 C3867:"point::output_x":非标准语法;使用"&"创建指向成员的指针
- 使用智能指针属性创建资源库函数?
- 通过指针算法调用结构的结构属性
- C++对象共享属性 - 使用指针或引用
- C++ 使用成员函数返回结构体指针属性的值
- 指向结构的指针保留某些属性,同时将其他属性重置为零(使用 map)
- 当我初始化了指针属性 allready 时,如何将 QGraphicsItem 向下投射到创建的类?
- 如何使用boost::graph dijkstra的算法,如果顶点属性是指针?
- 提升属性树:使用指向节点及其父节点的指针删除节点
- 如果使用类的指针属性来访问堆,如何避免非标量类型的错误
- QT UI指针中缺少属性和方法
- 访问派生属性和给定基指针的方法的更简单方法
- 访问指针类型的静态属性
- C++基类指针容器中,编辑特定对象的属性
- OpenGL顶点属性指针或着色器不工作