Virtual functions accepting inherited types

I'm trying to write a set of matrix classes. There is a null base class, matrix_base, and three inherited classes: full_matrix, sparse_matrix, and sparse_array. All three inherited classes need to perform matrix multiplication (and other operations) with all three types, returning different types in each case. Why doesn't the following work:

Code:

`class matrix_base {`

...

virtual matrix_base *mat_mult(matrix_base *cand)=0;

...

};

class full_matrix:public matrix_base {

...

virtual full_matrix *mat_mult(full_matrix *cand);

virtual full_matrix *mat_mult(sparse_matrix *cand);

virtual full_matrix *mat_mult(sparse_array *cand);

...

};

class sparse_matrix:public matrix_base {

...

virtual full_matrix *mat_mult(full_matrix *cand);

virtual sparse_array *mat_mult(sparse_matrix *cand);

virtual sparse_array *mat_mult(sparse_array *cand);

...

};

class sparse_array:public matrix_base {

...

virtual full_matrix *mat_mult(full_matrix *cand);

virtual sparse_array *mat_mult(sparse_matrix *cand);

virtual sparse_array *mat_mult(sparse_array *cand);

...

};

In other words, I want to store all three types in a common base class, perform multiplications between them transparently and have them return the desired type so that I can repeat the process.

C++ only allows me to define one of these virtual functions in each inherited class. Afterwards, it thinks that the function defines a field. Now there are two easy solutions to this.

1. I can define all three functions in the base class:

Code:

`class matrix_base {`

...

virtual matrix_base *mat_mult(full_matrix *cand)=0;

virtual matrix_base *mat_mult(sparse_matrix *cand)=0;

virtual matrix_base *mat_mult(sparse_array *cand)=0;

...

};

which requires a lot of forward declarations. Or, I can use if or switch statements to figure out which type is being passed to the inherited class:

Code:

`class sparse_array:public matrix_base {`

...

virtual matrix_base *mat_mult(matrix_base *cand) {

if (strcmp("sparse_matrix", (typeid(*cand).name)==0) { ...

...

};

In either case, it seems to me I'm doing C++'s job for it.