简体   繁体   中英

How to pass 2D array as read only to function by double pointer?

I need to pass double pointer, which points to the first element of 2D array, to function in way that prevents the function from modifying any element from 2D array. I thought I can do it with const reference - int** const &board , but it doesn't work like I expected. Moreover the 2D array cannot be declared as const, because it should be modifiable outside that function. How is such functionality possible? Here is working, simplified code in which I use it:

#include <iostream>

class player
{
public:
    player(){}
                                 // returns player move
    int move(int** const &board)
    {
        board[1][1] = 9; // should be illegal
        return 9;
    }
};

class game
{
    int** board;    
    player *white, *black;

public:
    game(player* player1, player* player2): white(player1), black(player2)
    {
        int i, j;

        board = new int* [8];

        for(i = 0; i < 8; i++)
        {
            board[i] = new int [8];
            for(j = 0; j < 8; j++)
                board[i][j] = 0;
        }
    }
                // gets moves from players and executes them
    void play() 
    {
        int move = white->move(board);

        board[2][2] = move; // should be legal
    }
                 // prints board to stdout
    void print() 
    {
        int i, j;

        for(i = 0; i < 8; i++)
        {
            for(j = 0; j < 8; j++)
                std::cout << board[i][j] << " ";
            std::cout << std::endl;
        }
    }

};

int main()
{
    game g(new player(), new player());

    g.play();
    g.print();
}

I saw your code, and the interesting part is this:

int move(int** const &board)
{
    board[1][1] = 9; // should be illegal
    return 9;
}

If you want board[1][1] = 9 to be illegal, then you've to declare the parameter as:

int move(int const** &board);
//int move(int** const &board); doesn't do what you want

There is a difference: int** const doesn't make the data read-only. See the error in second link:

It would be better if you write the parameter as:

int move(int const* const * const &board);

Because that makes everything const: all the following assignments would be illegal then:

board[1][1] = 9;  //illegal
board[0] = 0;     //illegal
board = 0;        //illegal

See the error here : http://www.ideone.com/mVsSL

Now some diagram:

int const* const * const
    ^       ^       ^
    |       |       |
    |       |       |
    |       |       this makes board = 0 illegal
    |        this makes board[0] = 0 illegal
    this makes board[1][1] = 9 illegal
void f(const int* const* arr)
{
    int y = arr[0][1];
    // arr[0][1] = 10; // compile error
    // arr[0] = 0; // compile error 
}

void g()
{
    int** arr;
    arr[0][1] = 10; // compiles
    f(arr);
}

No casts or copying necessary

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM