pokche
pokche

Reputation: 1149

How to return derived type while operating over base and derived class?

I have two classes, my_matrix and my_vector classes, where my_vector derives from my_matrix.

When I do my_matrix tmp = vec * mat, it returns a matrix (mat is an instance of my_matrix and vec is an instance of my_vector). I am fine here.

But when I do my_vector tmp = mat * vec, I get this error in clang++:

no viable conversion from 'my_matrix' to 'my_vector'

and this error in g++:

conversion from 'my_matrix' to non-scalar type 'my_vector' requested

I think I know what the problem is. After mat and vec are multiplied, the return type is my_matrix and you can't cast base class to derived class.

What do you think the solution for this would be?

I have tried defining void operator*(my_vector&, my_matrix&) (not a member function of the derived class) which calls my_vector operator*(my_matrix&) in the derived class, but it does not work so far.

class my_matrix{
public:
    my_matrix operator*(my_matrix& other_mat){
        my_matrix tmp(row, other_mat.col);
        // for loop to matrix multiply that fill up the tmp
        return tmp;
    }
};

class my_vector:public my_matrix{
public:
    // not sure if I need operator* here 
    // Somehow I want to bring the my_vector tmp = mat * vec;  here so 
    // it would return vector instead of matrix
    // I have tried : but not successful 
    // my_vector operator*(my_matrix&)
    // void operator*(my_vector&, my_matrix&); (non member)
};

int main(){
    my_matrix mat = {{1,2,3},{4,5,6}}; // 2x3
    my_vector vec = {1,2,3}; // 3x1

    my_vector tmp = mat * vec; // 2x3 * 3*1 gives 2x1 vector
}

Upvotes: 1

Views: 150

Answers (2)

Remy Lebeau
Remy Lebeau

Reputation: 595412

Try something like this:

class my_matrix {
public:
    my_matrix operator*(const my_matrix& other_mat) const {
        my_matrix tmp(row, other_mat.col);
        // for loop to matrix multiply that fill up the tmp
        return tmp;
    }
};

class my_vector : public my_matrix {
public:
    using my_matrix::operator*;

    my_vector operator*(const my_vector& other_vec) const {
        my_vector tmp(...);
        // for loop to vector multiply that fill up the tmp
        return tmp;
    }
};

my_vector operator*(const my_matrix &lhs, const my_vector &rhs)
{
    my_vector tmp(...);
    // for loop to vector multiply that fill up the tmp
    return tmp;
}

int main() {
    my_matrix mat = {{1,2,3},{4,5,6}}; // 2x3
    my_vector vec = {1,2,3}; // 3x1

    my_vector tmp = mat * vec; // 2x3 * 3x1 gives 2x1 vector
}

Upvotes: 1

Sam Varshavchik
Sam Varshavchik

Reputation: 118292

For starters, the existing operator*'s parameter is wrong:

my_matrix operator*(my_matrix& other_mat){

The parameter to the * operator should be const, and the method should be const itself. After all, the multiplication operator should not be modifying either of the operands:

my_matrix operator*(const my_matrix& other_mat) const {

With that problem out of the way, you can now meaningfully overload the operator:

my_vector operator*(const my_vector& other_mat) const {

And implement the multiplication operation in whatever way you want to define this operation to work.

Now, multiplication by a my_matrix returns in a my_matrix, and multiplication by a my_vector returns a my_vector. Your my_matrix overloads the * operator, and the return value becomes dependent on what you're multiplying it by.

Upvotes: 1

Related Questions