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
- It is not a pointer, because in your second dimension, you finally want to store the doubles, not pointers.
- 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
How to Determine the Highest and Lowest Value Using Do While Loops
Regex Match Digits Between Strings
How to Print Current Time (With Milliseconds) Using C++/C++11
How to Iterate Over the Words of a String
How to Tokenize a String in C++
When to Use Volatile With Multi Threading
System("Pause"); - Why Is It Wrong
Operator Overloading: Member Function Vs. Non-Member Function
How to Have All the Inputs on the Same Line C++
Two Dimensional Array With Random Numbers Doesn't Change
What Is the Copy-And-Swap Idiom
Rule-Of-Three Becomes Rule-Of-Five With C++11
Why Have Header Files and .Cpp Files
Parse (Split) a String in C++ Using String Delimiter (Standard C++)