У меня большая проблема, я хочу поместить матричный указатель объектов на функцию, но я не знаю, как это сделать, объекты, которые я использую, взяты из производного класса. Это пример моего кода. Примечание: класс Piece - это базовый класс, а класс Queen - производный класс от Piece

#include "Queen.h" 

void changeToQueen(Piece* mx)
{
    for (int i = 0; i < 8; i++)
    {
        for (int j = 0; j < 8; j++)
        {
            mx[i][j] = new Queen();
        }
    }

}
int main()
{
    Piece * matrix[7][7];
    changeToQueen(matrix); // this fails
    return 0;
}
0
Cristian Nunez Tapia 30 Май 2016 в 08:37

3 ответа

Лучший ответ

Вы можете изменить входной аргумент на void changeToQueen(Piece * mx[7][7]).

Или вы можете изменить входной аргумент на void changeToQueen(Piece** mx). Измените оператор присваивания на mx[7*i + j] = new Queen(); и передайте первый элемент как входной changeToQueen(&(matrix[0][0]));

Причина, по которой оба работают, заключается в том, что элементы многомерного массива непрерывно хранятся в памяти. Итак, все, что вам нужно, это указатель на первый элемент.

Оба решения немного ошибочны, потому что, если вам нужно изменить размеры вашей матрицы, вам придется немного изменить свой код. Изменение вашего прототипа на void changeToQueen(Piece** mx, size_t width, size_t height) будет полезно в будущем.

0
Janarth K 30 Май 2016 в 06:07

В качестве альтернативы это может быть способ справиться с вещами

template <unsigned int rows, unsigned int columns>
class Board
{
    public:
        Board() {}

        void    changeToQueen()
        {
            for (unsigned int y = 0 ; y < rows ; ++y)
            {
                for (unsigned int x = 0 ; x < columns ; ++x)
                { _pieces[y][x] = Queen(); }
            }
        }

        Piece   &at(unsigned int row, unsigned int column)
        { return _pieces[row][column]; } // you should check for out of range
        // you could either have a default null value for Piece to return, or throw an exception

    private:
        Piece   _pieces[rows][columns];
};

int main()
{
    Board<8,8>  board;

    board.changeToQueen();
    // return 0; // this is not mandatory in c++
}

Так что да, никаких указателей почти не волнует;)

Вы все еще хотите указатели ?? эээ ... ладно, может, вы могли бы это сделать: Piece *_pieces[rows][columns];, я не уверен, что вам это действительно нужно, но я не могу сказать, насколько это изменило бы ваш существующий код для этого.

0
vianney 30 Май 2016 в 07:24

Прежде всего, я не понимаю зависимостей между Queen и Piece, поэтому я предполагаю, что Piece является супертипом Queen и назначение Piece * mx = new Queen(); правильное .

Чтобы решить очевидную проблему несоответствия типов, вы можете изменить свой

  void changeToQueen(Piece* mx)

К

  void changeToQueen(Piece* mx[7][7])

И с изменением границы цикла на 7 (for (int i = 0; i < 7; i++)) или размера матрицы на 8 x 8 (с такими же циклами) это будет работать.

Но предлагаю продумать способ хранения данных. Возможно, вам нужно будет построить матрицу размера, отличного от 7x7, поэтому рассмотрим следующий пример, где для хранения матрицы используется динамическая память (в этом примере используется только Queen):

void changeToQueen(Queen*** &mx, int size)
{
    mx = new Queen**[size]; // allocation of memory for pointers of the first level
    for (int i = 0; i < size; i++)
    {
        mx[i] = new Queen*[size]; // allocation of memory for pointers of the second level
        for (int j = 0; j < size; j++)
        {
            mx[i][j] = new Queen(); // allocation of memory for object
        }
    }
}

int main()
{
    int m_size = 7;
    Queen *** matrix = NULL; // now memory not allocated for matrix

    changeToQueen(matrix, m_size);

    return 0;
}

Примечание: & вход void changeToQueen(Queen*** &mx, int size) позволяет изменить указатель Queen *** matrix; внутри функции changeToQueen

0
VolAnd 30 Май 2016 в 18:33