C++ Matrix Class

Creating Your Own Matrix Class

You can simply make the memory management automatic:

#include <cstddef>

template <typename T, std::size_t rows, std::size_t cols>
class Matrix {
public:
Matrix() { }
T * operator[](std::size_t x) {
return data[x];
}
private:
T data[rows][cols]{};
};

But if you must use dynamic memory allocations:

#include <cstddef>
#include <type_traits>
#include <cstring>
#include <initializer_list>
#include <utility>

template <typename T, std::size_t rows, std::size_t cols>
class Matrix {
private:
T *data{new T[rows * cols]};
public:
Matrix() { }
~Matrix() {
delete[] data;
data = nullptr; // crash on use after free
}
template<typename U>
Matrix(std::initializer_list<std::initializer_list<U>> list)
: data (static_cast<T*>(operator new[](sizeof(T) * rows * cols, static_cast<std::align_val_t>(alignof(T))))) {
std::size_t i = 0;
for (auto &lst : list) {
std::size_t j = 0;
for (auto &t : lst) {
std::construct_at<T>(&(*this)[i][j], std::forward<const U>(t));
++j;
}
++i;
}
}
Matrix(const Matrix &other) {
*this = other;
}
Matrix(T &&other) : data(other.data) {
other.data = nullptr;
}
Matrix & operator=(const Matrix &other) {
if constexpr (std::is_aggregate_v<T>) {
memcpy(data, other.data, sizeof(T) * rows * cols);
} else {
for (std::size_t i = 0; i < rows; ++i) {
for (std::size_t j = 0; j < cols; ++j) {
(*this)[i][j] = other[i][j];
}
}
}
return *this;
}
Matrix operator=(Matrix &&other) {
swap(data, other.data);
return *this;
}
const T * operator[](std::size_t x) const {
return &data[x * cols];
}
T * operator[](std::size_t x) {
return &data[x * cols];
}
};

#include <iostream>

int main() {
Matrix<int, 2, 2> a{{{1, 2}, {3, 4}}};
Matrix<int, 2, 2> b{a};
std::cout << b[0][0] << " " << b[0][1] << std::endl;
std::cout << b[1][0] << " " << b[1][1] << std::endl;
}

Note: This is a column Matrix. If you want a Row matrix you have to swap indexes around.

matrix class template,the multiplication or addition of different types of matrices

You can use a friend declaration

template <typename T>
class Matrix
{
template <typename U>
friend class Matrix;

// ...
};

Matrix Class in C++: An Explanation

In memory, a two dimensional array (n, m) looks more or less like this

_coef -> | _coef[0] -> {1, 2, 3, ..., m}
| _coef[1] -> {1, 2, 3, ..., m}
| _coef[2] -> {1, 2, 3, ..., m}
| ...
| _coef[n] -> {1, 2, 3, ..., m}

_coef points to an array of n pointers. And each of these pointers point to an array of m doubles.

So, in your case _coef points to an array of 1 pointer and this pointer points to an array of one double.

Now to your questions

  1. It is not a pointer, because in your second dimension, you finally want to store the doubles, not pointers.
  2. It is assigned to _coef[0], because it is the first, and only, row of your two dimensional array.

C++ Program with matrix class ending abruptly

Since the 2D array, vtr is created when declaring the Matrix object, you can move the vtr creation after reading the console input like below.

Matrix(int m = 2, int n = 2)
{
/*rows = m;
cols = n;
vtr = new int*[m];
for (int i = 0; i < m; i++)
{
vtr[i] = new int [n];
}

for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
vtr[i][j] = 0;
}
}*/
}

void read()
{
cout << "Enter the number of rows and columns of Matrix separated by a space: ";
cin >> rows >> cols;

vtr = new int*[rows];
for (int i = 0; i < rows; i++)
{
vtr[i] = new int [cols];
}

//Matrix a(rows, cols);
//write();

for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
cout << "(" << i << "," << j << ") : ";
cin >>vtr[i][j];
}
}

write(); //Prints the array
}


Related Topics



Leave a reply



Submit