C ++:如何在此抽象类的方法中返回抽象类

时间:2017-06-04 21:41:41

标签: c++ polymorphism abstract-class

我有一个抽象类,它有两个派生类。我正在尝试在基类中重载operator +,所以我可以像这样执行derivedClass = derivedClass + differentDerivedClass:

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

class UsualMatrix : public iMatrix

class SparseMatrix : public iMatrix 

在主要内部,我想做

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

我有复制构造函数和所有可能有用的东西。现在,如果我创建像

这样的函数
iMatrix operator+(const iMatrix& obj)

编译器(Xcode中的LLVM)说“返回类型'iMatrix'是一个抽象类”,但理论上其他一切都应该正常工作。我已经阅读了手册和其他StackOverflow线程,所以我试过这个:

iMatrix& operator+(const iMatrix& obj)

虽然函数本身确实“向此添加obj”并返回* this。问题是当我做c = a + b时,a变得等于c,但不应该改变。

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 

我该怎么办?必须在基类内部实现加法和乘法,我不知道如何修复此错误。 任何建议都将不胜感激,谢谢。

2 个答案:

答案 0 :(得分:2)

您的意图设计的问题是抽象返回类型。无法通过值返回抽象类。只能通过值返回具体类。因此,要返回抽象类,您需要一个指针或引用。

不幸的是,这不适用于operator+()

的语义
  • 要么通过引用返回当前对象,要么通过操作进行更改;但这不符合预期的语义,而且可能导致错误的答案(例如在做c = a+b+a+b;时)
  • 或者您将返回对临时对象的引用。但这将是UB,因为temporaray对象将在函数返回时降低,使得引用无关紧要。
  • 最后operator+无法自行决定用于返回的具体类型。例如:SparseMatrix a; UsualMatrix b; a+b;什么应该是矩阵a + b的类型?

您可以在运算符中使用多态和抽象类型,但不能作为返回类型。要实现此类操作,您需要选择自己的一组操作符,并让调用者手动管理临时结果:

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

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

答案 1 :(得分:0)

一个解决方案可能是非成员功能,如下所示:

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;
}

因为iMatrix是一个抽象类,所以不能返回它的实例。在上面的示例中,我们为operator+的所有派生类T重载iMatrix,我们可以返回T个实例。