c++ - 如何限制矩阵类只得到 'X' 'O' 或 '.'

标签 c++ c++11 visual-c++

我有一个棋盘类,可以制作 N*N 个字符棋盘。

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 时

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

它正在将矩阵中的这个位置更改为“X”和任何其他字符。

我需要将此矩阵限制为仅“X”、“O”或“.”

我不允许链接主类!我只能更改类。

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

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

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

这是我写的整个类:

#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;
    }
};

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

#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[] 返回该对象,然后在它的赋值运算符中执行您的逻辑。看起来像

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");
}

关于c++ - 如何限制矩阵类只得到 'X' 'O' 或 '.',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59214714/

相关文章:

c++ - 逗号的左侧操作数无效 VS 逗号的右侧操作数无效

c++ - 构造函数中没有匹配的调用函数 - C++ 11

c++ - 传递给 std::variant 的预定义类型列表

c++ - 不使用线性和二进制查找未排序数组的最大数量

c++ - 为什么这个 C++11 std::regex 示例抛出 regex_error 异常?

c++ - C2664 : while compiling in 64bit

c++ - 如何在 C++ 中跟踪对一组预定义函数的所有调用?

visual-c++ - 如何使用 IFileDialogCustomize::GetEditBoxText() 方法?

c++ - 将结构传递给 vector ,打印 vector 会产生奇怪的结果

c++ - 单步构建目标时如何预编译头文件?