C ++: how to return an abstract class to a method of that abstract class

I have an abstract class and it has two derived classes. I'm trying to overload operator + in a base class, so I could make a derived class = derived class + anotherDerivedClass like this:

class iMatrix{
iMatrix operator+(const iMatrix& obj)
}

class UsualMatrix : public iMatrix

class SparseMatrix : public iMatrix 

      

Inside main, I want to do

SparseMatrix a, b;
UsualMatrix c=a+b;

      

I have copy constructors and whatever might be useful. Now if I create a function like

iMatrix operator+(const iMatrix& obj)

      

The compiler (LLVM in Xcode) says, "The return type 'iMatrix' is an abstract class," but in theory everything else should work as expected. I've read tutorials and other StackOverflow threads, so I've tried this:

iMatrix& operator+(const iMatrix& obj)

      

Whereas the function itself "adds obj to this" and returns * this. The problem is, when I do c = a + b, a becomes equal to c, but it shouldn't be changed.

a=
1 1 
1 1 
b=
1 1 
1 1 
a+b=c; 
c=
2 2 
2 2 
b=
1 1 
1 1 
a=
2 2 
2 2 

      

What should I do? Addition and multiplication must be implemented inside the base class and I have no idea how to fix this error. Any advice would be appreciated, thanks.

+3


source to share


2 answers


One solution could be a non-member function like this:

template <
  typename T,
  typename = typename std::enable_if<std::is_base_of<iMatrix, T>::value>::type
>
T operator+(T const & a, T const & b) {
   T res; 
   // calculate res
   return res;
}

      



Since it iMatrix

is an abstract class, you cannot return an instance of it. In the above example, we are overloading operator+

for all derived classes T

of iMatrix

, and we can return instances T

.

0


source


The problem with your intentional design is the abstract return type. Abstract classes cannot be returned by value. Only specific classes can be returned by value. So, you need a pointer or reference to return an abstract class.

Unfortunately this won't work with semantics operator+()

:

  • either you return by reference to the current object, or change it using an operation; but this does not match the expected semantics and, moreover, may lead to incorrect answers (e.g. on execution c = a+b+a+b;

    )
  • or you will return a reference to a temporary object. but that will be UB because the timearay object will shrink when the function returns, making the reference irrelevant.
  • Finally operator+

    will not be able to independently define the specific type to use for the return. For example: SparseMatrix a; UsualMatrix b; a+b;

    what should be the type to be used for matrix a + b?


You can use polymorphic and abstract types inside operators, but not as a return type. To do things like this, you need to choose your own set of statements and let the manager manage the temporary results manually:

UsualMatrix c,tmp; 
SparseMatrix a,b,x; 
...
a.add(b, tmp);
tmp.add(x, c);   // c = a+b+x; 

      

from virtual void add(const iMatrix& x, iMatrix z) = 0;

+2


source







All Articles