如何限制矩阵类以仅获取“ X”,“ O”或“。” [英] How to limit a matrix class to get only 'X' 'O' or '.'

查看:61
本文介绍了如何限制矩阵类以仅获取“ X”,“ O”或“。”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个董事会课程,可以制作N * N个字符。

I have a board class that makes N*N board of chars.

class Cell
{ 
public:
    int row; int col;
};


class Board {
private:
    int size;
    char** matrix = nullptr;
   //many other class functions.
char & operator[](const Cell& cellToChange) {
        if (cellToChange.row < size && cellToChange.col < size) {
            return matrix[cellToChange.row][cellToChange.col];
        }
        else {
            cout << "ERROR!" << endl;
        }
    }

现在我在主体中使用时this

now when I use in the main this

"board1[{1, 4}] = 'X';"

它将矩阵中的此位置更改为'X'和其他任何字符。

It is changing this place in the matrix to 'X' and any other char.

我需要将此矩阵限制为仅'X''O'或'。

I need to limit this matrix to only 'X' 'O' or '.'

我不允许

我无法实现的目标不是使程序在尝试执行时打印错误

My goal I can not achieve right not is to make the program print "error" when I"m trying to do

"board1[{1, 4}] = 'z'".

我浪费了很多时间来实现它,我真的需要您的帮助。

And I have wasted hours on hours trying to achieve it and I really need your help here.

这是我写的整个课程:

#include <iostream>
using namespace std;


class Cell
{ 
public:
    int row; int col;
};


class Board {
private:
    int size;
    char** matrix = nullptr;

public: 

    Board(int sizeToSet) {                       //constructor with size
        size = sizeToSet;

        matrix = new char*[size];                 //creates a matrix
        for (int i = 0; i < size; i++)
            matrix[i] = new char[size];

        for (int i = 0; i < size; i++) {          //makes every cell in matix '.'
            for (int j = 0; j < size; j++) {
                matrix[i][j] = '.';
            }
        }
    }



    void printSize() {                            //matrix size print
        cout << size << endl;
    }

    ~Board() {                                    //destructor
        for (int i = 0; i < size; i++)
            delete[] matrix[i];
        delete[] matrix;
    }

    Board(const Board& other) {                   //copy constructor
        if (this != &other) {
            size = other.size;
            matrix = new char*[size];

            for (int i = 0; i < size; i++)
                matrix[i] = new char[size];

            for (int i = 0; i < size; i++) {
                for (int j = 0; j < size; j++) {
                    matrix[i][j] = other.matrix[i][j];
                }
            }
        }
    }

    Board(Board&& other) {                   //move constructor
        size = other.size;
        matrix = other.matrix;
        other.matrix = nullptr;
    }



    friend ostream& operator<<(ostream& os, const Board& boardToPrint) {       //prints matrix
        for (int i = 0; i < boardToPrint.size; i++) {
            for (int j = 0; j < boardToPrint.size; j++) {
                os << boardToPrint.matrix[i][j] << "  ";
            }
            os << endl;
        }
        os << endl;
        return os;
    }


    char & operator[](const Cell& cellToChange) {
        if (cellToChange.row < size && cellToChange.col < size) {
            return matrix[cellToChange.row][cellToChange.col];
        }
        else {
            cout << "ERROR!" << endl;
        }
    }

    void operator=(char charToAdd) {
        if (charToAdd == 'X' || charToAdd == 'O' || charToAdd == '.') {
            for (int i = 0; i < size; i++) {         
                for (int j = 0; j < size; j++) {
                    matrix[i][j] = charToAdd;
                }
            }
        }
        else {
            cout << "ERROR!" << endl;
        }
    }

    const Board& operator=(const Board& other) {
        if (this != &other) {
            size = other.size;
            matrix = new char*[size];

            for (int i = 0; i < size; i++)
                matrix[i] = new char[size];

            for (int i = 0; i < size; i++) {
                for (int j = 0; j < size; j++) {
                    matrix[i][j] = other.matrix[i][j];
                }
            }
        }
        return *this;
    }
};

这是我不允许更改的全部主要内容:

and this is the whole main I"m not allowed to change:

#include "Board.h"

#include <iostream>
using namespace std;

int main() {
    Board board1{4};  // Initializes a 4x4 board
    cout << board1 << endl;   /* Shows an empty board:
    ....
    ....
    ....
    ....
    */
    cout << board1[{1,2}] << endl; // .
    board1[{1,1}]='X';
    board1[{1,2}]='O';
    char c = board1[{1,2}]; cout << c << endl; // O
    cout << board1 << endl;  /* Shows the following board:
    ....
    .XO.
    ....
    ....
    */
    // This should raise an exception
    //  "Illegal"
    board1 = '.';     // Fill the entire board with "."
    cout << board1 << endl;  /* Shows an empty board, as above */
    board1 = 'a';        // This should raise exception
    //  "Illegal"
    board1[{0,1}] = 'x';  // This should raise an exception
    //   "Illegal"

    Board board2 = board1;
    board2[{0,0}] = 'X';
    cout << board1 << endl;  /* Shows an empty board, as above */
    cout << board2 << endl;  /* Shows a board with an X at top-left */

    board1 = board2;
    board1[{3,3}] = 'O';
    cout << board2 << endl;  /* Shows a board with an X at top-left */
    cout << board1 << endl;  /* Shows a board with an X at top-left and O at bottom-right */

    cout << "Good bye!" << endl;

    return 0;
}

谢谢!

推荐答案

您需要的是另一层抽象。由于您无法控制分配的右侧,因此需要控制分配操作符。为此,您需要一个代理对象。您将通过 operator [] 返回该对象,然后使用其赋值运算符进行逻辑处理。看起来像是

What you need is another layer of abstraction. Since you can't control the right hand side of the assignment, you need to control the assignment operator. To do that, you need a proxy object. You'll return that object from the operator[] and then you do your logic in it's assignment operator. That would look like

class Proxy
{
    char& val;
    Proxy(char& val) : val(val) {}
    Proxy& operator=(char new_val)
    {
        if (new_val == 'X' || new_val == 'O' || new_val == '.')
        {
            val = new_val;
            return *this;
        }
        throw std::invalid_argument("Invalid Assignment.  Use X, O, or .");
    }
    // allows this class to implicitly convertible to a char
    operator char() { return val; }
};

Proxy operator[](const Cell& cellToChange) {
    if (cellToChange.row < size && cellToChange.col < size) {
        return {matrix[cellToChange.row][cellToChange.col]};
    }
    throw std::out_of_range("invalid index");
}

这篇关于如何限制矩阵类以仅获取“ X”,“ O”或“。”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆