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



我有一个抽象类,它有两个派生的类。我正在尝试在基类中超载运算符 ,因此我可以做derivedClass = derivedClass DifferendDerivedClass类似:

class iMatrix{
iMatrix operator+(const iMatrix& obj)
}
class UsualMatrix : public iMatrix
class SparseMatrix : public iMatrix 

在Main内部,我想做

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

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

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

编译器(Xcode中的LLVM(说"返回类型'imatrix'是一个抽象类",但从理论上讲,其他所有内容都应正常工作。我已经阅读了手册和其他stackoverflow线程,所以我尝试了此操作:

iMatrix& operator+(const iMatrix& obj)

虽然函数本身确实是"将OBJ添加到此"并返回 *。问题是当我做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 

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

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

不幸的是,这与operator+()的语义不合适:

  • 您要么通过引用当前对象返回,然后使用操作更改;但这不符合预期的语义,此外可能会导致错误的答案(例如,在执行c = a+b+a+b;时(
  • 否则您将引用引用到临时对象。但这将是UB,因为临时对象将在函数返回时退化,从而使参考无关。
  • 最后,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;

一种解决方案可以是 non-ember 函数这样的函数:

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是一个抽象类,因此您无法返回其实例。在上面的示例中,我们对iMatrix的所有派生类Toperator+超载,我们可以返回T实例。

最新更新