I have templated MxN matrix class
template<typename T, size_t M, size_t N>
class Matrix {
public:
Matrix() { vecs_ = new Vector<T, N>[M]; }
Matrix(std::initializer_list<std::initializer_list<T>> l);
Matrix(const Matrix& m);
~Matrix() { delete[] vecs_; }
Matrix& operator=(const Matrix& m);
Matrix& operator+=(const Matrix& m);
Matrix& operator-=(const Matrix& m);
Matrix& operator*=(T c);
Matrix& operator/=(T c);
Vector<T, N> operator[](int row) const;
Vector<T, N>& operator[](int row);
Vector<T, M> operator*(const Vector<T, N>& b) const;
template<size_t P> Matrix<T, M, P> operator*(const Matrix<T, N, P>& b) const;
Matrix<T, N, M> Transpose() const;
size_t Rows() const { return M; }
size_t Columns() const { return N; }
protected:
Vector<T, N>* vecs_;
};
template<typename T, size_t M, size_t N> Matrix<T, M, N> operator+(const Matrix<T, M, N>& m) { return m; }
template<typename T, size_t M, size_t N> Matrix<T, M, N> operator-(const Matrix<T, M, N>& m) { return Matrix<T, M, N>() - m; }
template<typename T, size_t M, size_t N> Matrix<T, M, N> operator+(const Matrix<T, M, N>& a, const Matrix<T, M, N>& b) { return a += b; }
template<typename T, size_t M, size_t N> Matrix<T, M, N> operator-(const Matrix<T, M, N>& a, const Matrix<T, M, N>& b) { return a -= b; }
template<typename T, typename U, size_t M, size_t N> Matrix<T, M, N> operator*(Matrix<T, M, N> m, U c) { return m *= c; }
template<typename T, typename U, size_t M, size_t N> Matrix<T, M, N> operator*(U c, Matrix<T, M, N> m) { return m *= c; }
template<typename T, typename U, size_t M, size_t N> Matrix<T, M, N> operator/(Matrix<T, M, N> m, U c) { return m /= c; }
template<typename T, size_t M, size_t N>
std::ostream& operator<<(std::ostream& os, const Matrix<T, M, N>& m) { ... }
I wish to create NxN square matrix class that is derived from MxN matrix. This child class should inherit everything the parent have, including its operator overloads. This is what I tried
template<typename T, size_t N>
class SquareMatrix : public Matrix<T, N, N>
{
public:
using Matrix<T, N, N>::Matrix; // inherit all constructors from the base class
using Matrix<T, N, N>::operator=; // also inherit other operators
using Matrix<T, N, N>::operator+=;
using Matrix<T, N, N>::operator-=;
using Matrix<T, N, N>::operator*=;
using Matrix<T, N, N>::operator/=;
using Matrix<T, N, N>::operator*;
SquareMatrix(bool identity);
};
Is it a proper way to inherit? Are there any redundant lines? Is there anything else I need to add?
Also, I have problems with * and [] operator. In the parent matrix class, I have two overloads for each of these operators, each takes different parameter. Is there any way to distinguish between these two in the child square matrix class? using Matrix<T, N, N>::operator*; is bit ambiguous to compile.
I imagine all your functions work with matrices of arbitary sizes right? If i manually declare 2 square matricies:
Matrix<int, 5, 5> m1, m2;
Do operations work on them? If so, then you don't need inheritance, you just need to make it easy for the user to make this specific version of the matrix type, which you can achieve with a type alias:
template<typename T, size_t N>
using SquareMatrix = Matrix<T, N, N>;
And everything should just work.
If you want to add functions that are specific to the square matrix, aim to make them free functions:
template <typename T, size_t N>
constexpr SquareMatrix<T, N> identity() noexcept {
...
}
This gives you a nice abstraction and is very modern c++ style. AKA, a matrix could easily be set as follows:
auto m = matrix::identity<int, 5>();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With