У меня большая проблема, я хочу поместить матричный указатель объектов на функцию, но я не знаю, как это сделать, объекты, которые я использую, взяты из производного класса. Это пример моего кода. Примечание: класс 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;
}
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)
будет полезно в будущем.
В качестве альтернативы это может быть способ справиться с вещами
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];
, я не уверен, что вам это действительно нужно, но я не могу сказать, насколько это изменило бы ваш существующий код для этого.
Прежде всего, я не понимаю зависимостей между 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
Похожие вопросы
Новые вопросы
c++
C++ — это язык программирования общего назначения. Изначально он разрабатывался как расширение C и имел аналогичный синтаксис, но теперь это совершенно другой язык. Используйте этот тег для вопросов о коде, который будет скомпилирован с помощью компилятора C++. Используйте тег версии для вопросов, связанных с конкретной стандартной версией [C++11], [C++14], [C++17], [C++20] или [C++23]. и т.д.