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确切地说,应该发生什么?