析构函数和类属性的指针

Vid*_*dak 0 c++ constructor pointers destructor memory-management

我有这个类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();

};
Run Code Online (Sandbox Code Playgroud)

我有它的构造函数,它创建了棋盘的开始阶段:(非常可怕,我知道:))

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);
            }
        }       
}
Run Code Online (Sandbox Code Playgroud)

我还需要有一个ChessBoard的析构函数,它是这样的:

ChessBoard::~ChessBoard()
{
    //for(int i = 0; i < 8; i++)
    //  delete board[i];
    delete [] board;
}
Run Code Online (Sandbox Code Playgroud)

部分注释的原因是我的第一个问题:

1.为什么我不能用上面写的方法删除所有字段?当我尝试这样做时,程序进入"块类型有效"错误,我知道这是由于尝试删除不存在的内存引起的.当我评论它时,程序运行完美.ChessBoard是一个矩阵8x8,所以我应该可以像我在这里尝试一样删除它.

我的第二个问题是:

2.如何删除国际象棋棋盘构造函数中存在的数字(King,Queen,Rook ......)指针?令人困惑的是因为这些指针被用作我的国际象棋棋盘的一部分,我使用它们直到程序结束.当程序结束时,我需要释放我的记忆,但我不知道如何访问这些指针.数字本身会被自动删除,因为它们都是非指针.我是否甚至需要删除那些指针,看到我一直使用它们直到最后,然后一切都被释放了?

Lal*_*and 6

  1. 新/删除的一般规则是调用必须相互匹配.你创建你的董事会

    board = new Field*[8];
    for(i = 0; i < 8; i++)
    {
        board[i] = new Field[8];
    }
    
    Run Code Online (Sandbox Code Playgroud)

    您将需要以相同的方式删除您的电路板,但向后:

    for(i = 0; i < 8; i++)
    {
        delete [] board[i];
    }
    delete[] board;
    
    Run Code Online (Sandbox Code Playgroud)

    由于这不起作用,我猜你的问题是双重删除.其他东西正在释放阵列.您是否有可能拥有指向同一场**的ChessBoard副本?

  2. 您将不得不以类似的方式删除您的数字.

    for (int x = 0; x < 8; x ++)
    for (int y = 0; y < 8 ;y ++)
    if (board[y][x] != NULL)
         delete board[y][x];
    
    Run Code Online (Sandbox Code Playgroud)

    只要您从代码中删除图形的代码删除该图形并将该图形的位置设置为NULL,此代码就会起作用.

    2B.你的2个问题的第二部分是你是否必须完成任何删除,因为程序正在结束.你是对的,因为如果你要立即退出,你不需要删除任何东西,操作系统会为你释放所有内存.

通常应该不过,通常你结束了,让他们运行多次修改大部分程序,然后你为每次运行使用稍多的内存有内存泄漏.


这就是如何解决你提出的问题.但是,我强烈建议您更改此代码的大部分样式并删除所有动态分配.

首先,使用常规静态大小的数组(Field [8] [8])来存储字段.我的意思是,象棋场何时会改变大小?

其次,按值存储件.如果件位于某个位置,则您的字段类已存储.还有Field类存储一个表示类型的枚举.没有理由为您的作品使用动态分配.

第三,没有必要检查返回是否new为NULL.如果有错误,它将抛出一个异常,你的程序将停止(因为它应该没有太多你可以做的内存不足).