Hi, I'm creating a class called Matrix (basically 2D vectors), and a class SqMatrix (square matrix) inherits from Matrix, with methods like finding the determinant and the inverse, I also overloaded some operators like =, +, * to do basic arithmatic of matrices.
Now I have a problem: the operators return Matrix (or references to Matrix) objects, and now I also want SqMatrix to be able to use them (because the arithmatic are very similar) but they return Matrix, slicing down the SqMatrix "properties" of the objects.
I've thought of some ways to handle this:
1. Copy and paste the implementations and make minor changes
(which is not wise and makes the code hard to maintain)
2. Overload = to convert an object between Matrix and SqMatrix
(is this possible and, is this safe?)
3. Do not inherit from Matrix and simply declare all methods needed in the class Matrix
(but I don't want Matrix to do some occasionally impossible tasks, like finding the determinant)
4. Make a template to allow the return for whatever type (either Matrix or SqMatrix)
(are templates designed to work this way? Plus, what should be the template be - Matrix is general enough to be a base and Matrix shouldn't be a type of anything...)
Please note that a Matrix would end up to be a SqMatrix during calculations, so it seems that I have to use No.2...
Are there better designs?
Thanks very much.
EDITED: The declarations are quite long so I truncate them a little bit
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
|
class Matrix
{
public:
// constructors
Matrix(unsigned int m, unsigned int n); // an m by n matrix
Matrix();
// need copy ctor!
virtual ~Matrix() {}
// some methods to access the content...or to print
double GetElement(unsigned int row, unsigned int col) const
{ return itsMatrix[row][col]; }
void SetElement(double element, unsigned int row, unsigned int col)
{ itsMatrix[row][col] = element; }
void Input();
void Print();
// ...
// operations
void Trans(); // transpose
// overloaded operators
Matrix & operator= (const Matrix &);
Matrix operator+ (const Matrix &);
Matrix operator- (const Matrix &);
Matrix operator* (const double);
Matrix operator* (const Matrix &);
protected:
vector< vector<double> > itsMatrix;
};
// ========================================
class SqMatrix : public Matrix
{
public:
// constructors
SqMatrix(unsigned int n): Matrix(n, n) {} // a square matrix of size n
SqMatrix(): Matrix() {}
// need copy ctor!
~SqMatrix() {}
// opearations
SqMatrix Adj() const; // adjoint
double Det() const; // determinant
SqMatrix Min(unsigned int row, unsigned int col) const; // minor
double Cof(unsigned int row, unsigned int col) const; // cofactor
SqMatrix Inv() const; // inverse
// ...
};
|
Hmm...I've seen people using like
double**
, is this better as you can move the whole thing to the heap?