Safely casting a Base to a Derived without using the heap

I am fairly new to the concept of inheritance, and I am constructing a Matrix class and a derived SquareMatrix class. Some of my methods depend on safely casting a Matrix to a SquareMatrix. I have heard of something called copy-constructors, but I don't think they work the way I have tried to use them. I tried to use

1
2
3
4
5
SquareMatrix::SquareMatrix(const Matrix& A)
 : Lptr(0), Uptr(0), Pptr(0), multiplier(1), determinant(0)
{
    this->matrixData = A.matrixData;
}


but, for some reason, it is saying that my Matrix::matrixData is bad! (and I KNOW this is simply not the case, as it has worked for BOTH classes in my other methods). I wish to, without using the heap, make a copy constructor so that I can safely make a Matrix a SquareMatrix. I was about to use some of the casting techniques here, http://www.cplusplus.com/doc/tutorial/typecasting/ , namely this one: *(dynamic_cast<SquareMatrix*>(this->getTranspose())) in the place of this->getTranspose(), for example, but I don't know if it has to be on the heap (I wish to AVOID putting it on the heap, as both classes will have so many methods).

Is there any safe way around this problem? (Note: I could always do a reinterpret_cast, but from the aforementioned article, it is a means to an end.

EDIT:

My declaration of matrixData is, of course, in base class, Matrix, and is declared as:
1
2
protected:
        std::vector<std::vector<long double> > matrixData;


The error I am getting is:
 
error: 'std::vector<std::vector<long double, std::allocator<long double> >, std::allocator<std::vector<long double, std::allocator<long double> > > > 

within this context


It signals the error from Matrix.h, even though SquareMatrix is supposed to have it as well.

If it helps any, here is the full code in both Matrix.h, SquareMatrix.h:

Matrix.h
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
#ifndef MATRIX_H
#define MATRIX_H
#include <iostream>
#include <vector>

class Matrix
{
    public:
        Matrix();
        Matrix(const std::vector<std::vector<long double> >&);
        ~Matrix(); //for releasing any dynamically allocated memory
        //getter functions
        unsigned getRowCount() const;
        unsigned getColumnCount() const;
        //for transposing a Matrix
        Matrix getTranspose() const;
        static Matrix transpose(const Matrix&);
        //returns filled Matrix
        static Matrix createFilledMatrix(unsigned, unsigned, long double);
        //overloading operators to simplify Matrix arithmetic
        Matrix operator+(const Matrix&);
        Matrix operator-(const Matrix&);
        Matrix operator*(const Matrix&);
        Matrix operator*(long double);
        friend Matrix operator-(const Matrix&);
        friend Matrix operator*(long double, const Matrix&);
        friend std::ostream& operator<<(std::ostream& , const Matrix& );
    protected:
        std::vector<std::vector<long double> > matrixData;
        virtual void validateData();
        //members
    private:
        //still trying to decide on how to implement pseudoInverse(), inverse.
        //My best bet here would be to make it all private and force the user of this code to make a friend function/class to get
        //it. Either way, I will need a destructor.
};

#endif // MATRIX_H 


SquareMatrix.h

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
#ifndef SQUAREMATRIX_H
#define SQUAREMATRIX_H
#include "Matrix.h"
#include <vector>

class SquareMatrix : public Matrix
{
    public:
        SquareMatrix();
        SquareMatrix(const Matrix&);
        SquareMatrix(std::vector<std::vector<long double> >);
        virtual ~SquareMatrix();    //remember, we are responsible for freeing any dynamic memory we explicitly use
        //the SquareMatrix version of createFilledMatrix()
        static SquareMatrix createFilledMatrix(unsigned, long double);
        //convenient member functions exclusive to SquareMatrix
        bool isUpperTriangularMatrix() const;
        bool isLowerTriangluarMatrix() const;
        bool isDiagonalMatrix() const;
        static SquareMatrix identityMatrix(unsigned);
        long double computeDeterminant();
        //getter version of computeDeterminant() which allows for efficient retrieval later (after computeDeterminant() has been called)
        long double getDeterminant() const;
        void PLUDecompose();
        //getter functions
        SquareMatrix getL() const;
        SquareMatrix getU() const;
        SquareMatrix getP() const;
    protected:
        void validateData();
    private:
        SquareMatrix *Lptr, *Uptr, *Pptr; //should be initialized by LUDecompose before using
        long double determinant;
        int multiplier;
};

#endif // SQUAREMATRIX_H 
Last edited on
We would really have to know the actual error.
SOLUTION: I found this stuff to fix the error: http://stackoverflow.com/questions/3319892/c-why-does-my-derivedclasss-constructor-not-have-access-to-the-baseclasss-p . I fixed my copy constructor by defining it as:
1
2
3
4
5
6
//copy constructor
SquareMatrix::SquareMatrix(const Matrix& A)
 : Matrix(A), Lptr(0), Uptr(0), Pptr(0), determinant(0), multiplier(1)
{

}
Nice.

That isn't a copy constructor though . Copy constructors take a const reference to the type that they are:
SquareMatrix::SquareMatrix( const SquareMatrix& );

You would still have to construct the Matrix:
1
2
SquareMatrix::SquareMatrix( const SquareMatrix& other )
  : Matrix( other ), // ... 


Oh, btw. I never would have known that you edited your post unless I saw that you made a post below it.
Last edited on
Topic archived. No new replies allowed.