defining operators in abstract class

Hello All,
I have a small question.

I have an abstract class called Mbase and from it derived two classes: Sparse and Dense.
Now I have an array in which its elements can be either Sparse or Dense. So, I delcared the array to have pointers to Mbase class.

for example:
1
2
3
4
5
Mbase** A;
Sparse* A1 = new Sparse;
Dense* A2 = new Dense;
A[1] = dynamic_cast<Mbase*>(A1);
A[2] = dynamic_cast<Mbase*>(A2);


Now, I have operator + defined in Sparse and Dense. but when I do
A[1]+A[2]
I get that operator + is not defined for Mbase class.

So, I tried to define it in the Mbase class
1
2
3
4
5
6
7
class Mbase{
public:
void put()=0;
double get()=0;

Mbase operator +(Mbase A);
}


However, the last code does not compile complaining that it cannot declare a class of type abstract in Mbase operator +(Mbase A). I think this is because I am returning Mbase instance.

Can you please tell me the solution for this kind of problem?

Thank you in advance


First, this is wrong as you are treating that area as an array and you haven't made space.
1
2
3
Mbase** A;
A[1] = ...
A[2] = ...


Second, Sparse and Dense are derived from Mbase, so you should not cast from these derived classes to the base. So the code becomes something like:
1
2
3
Mbase* A[2];
A[0] = new Sparse;
A[1] = new Dense;


Now that's out of the way, can you explain what Sparse + Dense means? At the moment it doesn't make a lot of sense to me as I don't know what Mbase, Sparse and Dense mean. But if I apply an analogous relationship, say Fruit, Apple, Orange, then it doesn't make sense to add Apple and Orange.

EDIT:
I've looked at one of your previous posts and I take it that these are Sparse and Dense Matrices, and the base class is a Matrix.

Well, the Matrix base class could have all the matrix type things, add, multiply and so on. These methods could call helper virtual methods like get cell(x, y) that return a value that the higher functions can use.
Last edited on
Thank you for your reply.

Yes, I mean a Dense and Sparse matices.
The code I have given is a sample of what I need to do.

What is actually done is I have a template class called Matrix<T> and derived from it Sparse<T> and Dense<T>.

The idea here is for example the Sparse<T> could have entries as double for example, Sparse<double>. However, what I want to do is that the matrix sparse can also contain another matrices.

For example:
 
Sparse<Dense*> A;

Which in this case means that A is sparse matrix that contains in it pointers to dense matrices.

Then I want to go one step further. I want matrix Sparse can contain any type of matrices.
 
Sparse<Mbase*> A;

Which means that A is sparse and its elements are pointers to an any kind of a matrix.

Now, the issue is when I need to add the entry at A(1,1) to another the entry of Matrix B(1,1). in other words.

(*A[1])+(*B[1])

However, since matrix A can contain any type of matrix, in other way, it contains pointers to Base class, then I must define the operator + for the base class as well, otherwise the compiler complains saying that class Mbase has no operator +.

And when I define operator + in Mbase

Mbase operator +(Mbase A);

The compiler again complains that cannot return MBase because it is abstract type.

So how can I define the operator for the MBase class.

Thanks
I hope I was able to describe what I want.



Your definition of Sparse has thrown me. Is your sparse matrix one of these? http://en.wikipedia.org/wiki/Sparse_matrix

What does the interface look like?
Your definition of Sparse has thrown me. Is your sparse matrix one of these? http://en.wikipedia.org/wiki/Sparse_matrix


Yes, exactly it is the same.

What does the interface look like?

do you mean the header file?
I meant the public methods of the class, but that doesn't matter now.

Anyway, if a sparse array is just a matrix that is mostly zero, it's still just a matrix right? I mean, the only difference is that it can be efficiently represented in much less space, but you do the same kind of operations on it as you would a dense matrix.

Presumably, as you added more and more data to a sparse matrix, it becomes worthwhile to represent it as a dense matrix. But that's just implementation. From the user's point of view, it's still the same matrix.

If that's the case, you need a Matrix class that has the interface that supports matrix stuff, but it's privately implemented using a sparse or dense matrix class. And as the properties of the values change, it may choose to swap one implementation for another.

So, in my view, users should be using Matrix<value-type>, which is associated with a SparseMatrix<value-type> or a DenseMatrix<value-type>. But I don't see any inheritance here at all. These implementation matrix classes may just have get cell/set cell methods that the main matrix class calls internally in its methods.
The idea here that I want the sparse matrix to have matrices in its entries.

For example

 
Sparse<MBase*> A(3,3); 


This declares a 3 by 3 matrix A. But intead of having numbers in A it will have pointers to MBase class. This is the same Idea as std::vectors. std::vectors can have entries of any type.

Now the issue is that I want to do operations on the entries

For example:
1
2
3
4
5
6
7
Sparse<MBase*> A(5,5); 
Sparse<MBase*> B(5,5); 

A[1] = new Dense(3,3);
B[1] = new Dense (3,3);

A[1]+B[1]   //this gives a compile error, operator + is not defined for MBase 


I want A[1]+B[1] to call the operator+ for Dense matrices

Thanks
I'm sorry, I can't give examples using your design because I think it's seriously flawed.

The idea here that I want the sparse matrix to have matrices in its entries.
No problem:
 
Matrix<Matrix<double> > a(3, 3);


Does the user of the matrix class care that the matrix is sparse or dense, or what kind of sparse matrix is used? If these need to be forced, it should just be a matter of setting attributes like:
 
a.SetType(Matrix::Dense);
Last edited on
Thank you,
That would be a good workaround.

But can I do it using inheritance. Can I have the matrix "a" contain the base class of all matrices. Then I can have more freedom.
A(1,1) -> dense
A(2,2) -> sparse
A(3,3) - > dense

and so on.


Thanks
Mina
We've gone full circle now.

Yes, you can use inheritance, but you'll need a set of static functions on the base class that do things like add, multiply, ... and the virtual functions on the base are methods like getcell/setcell. The static high level functions call the virtual cell functions to get and set values.

So your code would look like:
1
2
3
DenseMatrix a(2, 2);
SparseMatrix b(2, 2);
Matrix* c = Matrix::Add(&a, &b);
Which I think is ugly because if makes the user of your matrix classes responsible for memory management and knowing about the details of your class hierarchy. What if you had a classes that represented different kinds of sparse matrices?
Topic archived. No new replies allowed.