我有一个抽象类,它有两个派生的类。我正在尝试在基类中超载运算符 ,因此我可以做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
的所有派生类T
的operator+
超载,我们可以返回T
实例。