Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inheriting everything from base class

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.

like image 730
Jimmy Yang Avatar asked Dec 04 '25 04:12

Jimmy Yang


1 Answers

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>();
like image 170
Fantastic Mr Fox Avatar answered Dec 05 '25 17:12

Fantastic Mr Fox