I'm building a class that has an array variable, but I need to give the dimensions in the constructor to make the variable.
Some like:
class Table {
int array[dim][dim];
Table(int dim) {
array[dim][dim]; //???
}
}
What can I do?
I'm building a class that has an array variable, but I need to give the dimensions in the constructor to make the variable.
Some like:
class Table {
int array[dim][dim];
Table(int dim) {
array[dim][dim]; //???
}
}
What can I do?
What you need is to allocate the array dynamically at runtime.
You could use new[]
/delete[]
to allocate/free the array manually:
class Table {
int **array;
int arrDim;
Table(int dim) : arrDim(dim) {
array = new int*[dim];
for(int i = 0; i < dim; ++i) {
array[i] = new int[dim];
}
}
~Table() {
for(int i = 0; i < arrDim; ++i) {
delete[] array[i];
}
delete[] array;
}
};
You would also need to manually implement an operator=
, per the Rule of 3/5/0.
However, this issue is better handled using std::vector
instead:
#include <vector>
class Table {
std::vector<std::vector<int>> array;
Table(int dim) : array(dim, std::vector<int>(dim)) {}
};
Or:
#include <vector>
class Table {
std::vector<std::vector<int>> array;
Table(int dim) {
array.resize(dim);
for(int i = 0; i < dim; ++i) {
array[i].resize(dim);
}
}
};
If you are worry about speed and memory then it is better to use single continuous memory buffer for 2d arrays. Something like this.
#include <stdint.h>
#include <cassert>
#include <vector>
template <class T>
class array_2d
{
public:
template<typename U>
using ArrayT = std::vector<U>;
protected:
ArrayT<T> m_buffer;
uint32_t m_rows;
uint32_t m_columns;
inline uint32_t index(uint32_t row, uint32_t column) const {
assert(row >= 0 && row < m_rows && column >= 0 && column < m_columns);
return row*m_columns + column;
}
public:
array_2d(uint32_t rows, uint32_t columns) : m_rows(rows), m_columns(columns) { m_buffer.resize(rows*columns); }
array_2d(uint32_t rows, uint32_t columns, const T & elem) : m_rows(rows), m_columns(columns) { m_buffer.resize(rows*columns, elem); }
~array_2d() = default;
T &operator()(uint32_t row, uint32_t column) { return m_buffer[index(row, column)]; }
T &at(uint32_t row, uint32_t column) { return operator()(row, column); }
const T &operator()(uint32_t row, uint32_t column) const { return m_buffer[index(row, column)]; }
const T &at(uint32_t row, uint32_t column) const { return operator()(row, column); }
auto cbegin() const { return m_buffer.cbegin(); }
auto cend() const { return m_buffer.cend(); }
auto begin() { return m_buffer.begin(); }
auto end() { return m_buffer.end(); }
uint32_t size() const { return m_buffer.size(); }
};