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

C++ C++;:如何在此抽象类的方法中返回抽象类,c++,polymorphism,abstract-class,C++,Polymorphism,Abstract Class,我有一个抽象类,它有两个派生类。我正在尝试重载基类中的运算符+,以便可以执行以下操作: class iMatrix{ iMatrix operator+(const iMatrix& obj) } class UsualMatrix : public iMatrix class SparseMatrix : public iMatrix template < typename T, typename = typename std::enable_if<std:

我有一个抽象类,它有两个派生类。我正在尝试重载基类中的运算符+,以便可以执行以下操作:

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

class UsualMatrix : public iMatrix

class SparseMatrix : public iMatrix 
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;
}
里面的主要,我想做

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 
我该怎么办?加法和乘法必须在基类内部实现,我不知道如何修复这个错误。
任何建议都将不胜感激。

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

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

class UsualMatrix : public iMatrix

class SparseMatrix : public iMatrix 
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;
}
模板<
类型名T,
typename=typename std::enable_if::type
>
T运算符+(T常量和a、T常量和b){
T res;
//计算res
返回res;
}

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

您的设计问题在于抽象返回类型。抽象类不能按值返回。值只能返回具体类。所以,要返回抽象类,您需要一个指针或引用

不幸的是,这不适用于
操作符+()
的语义:

  • 或者通过引用返回当前对象,并随操作更改它;但这不符合预期的语义,而且可能导致错误的回答(例如,在执行
    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; 

使用
虚拟空添加(常量iMatrix&x,iMatrix z)=0

多态性和值语义不能很好地结合在一起。你真的需要一个抽象类型来表示矩阵吗?@juanchopanza是的,因为教我们抽象类和东西是大学的任务:)好吧,也许这应该是一个反例。您已经发现了这种方法的一个问题。对我来说,这似乎是一个很好的解决方案,但产生了相同的错误:“重载的‘运算符+’必须是一元运算符或二元运算符(有3个参数)”不要将其作为成员函数编写:-)@jonathanx64这种方法会破坏运行时多态性,不?@juanchopanza
运算符会发生什么+(T const&,U const&)
?当
U
T
都是派生类时?@amin确切地说,应该发生什么?