【问题标题】:C++: How to return abstract class in a method of this abstract classC++:如何在这个抽象类的方法中返回抽象类
【发布时间】:2017-06-04 21:41:40
【问题描述】:

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

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 添加到 this”并返回 *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 

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

【问题讨论】:

  • 多态性和值语义不能很好地结合在一起。
  • 真的需要抽象类型来表示矩阵吗?
  • @juanchopanza 是的,因为教我们抽象类和东西是大学的任务:)
  • 好的,所以也许它应该是一个反例。您已经发现这种方法存在一个问题。

标签: c++ polymorphism abstract-class


【解决方案1】:

您打算设计的问题是抽象返回类型。抽象类不能按值返回。只有具体的类才能按值返回。因此,要返回抽象类,您需要一个指针或引用。

很遗憾,这不适用于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;

【讨论】:

    【解决方案2】:

    一种解决方案可能是这样的非成员函数:

    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 实例。

    【讨论】:

    • 这对我来说似乎是一个很好的解决方案,但会产生同样的错误:“重载的 'operator+' 必须是一元或二元运算符(有 3 个参数)”
    • 不要把它写成成员函数 :-) @JonathanX64
    • 这种杀死运行时多态,不是吗?
    • @juanchopanza operator+(T const &amp;, U const &amp;) 会发生什么?当UT 都是派生类时?
    • @amin 对了,应该怎么办?
    猜你喜欢
    • 2010-12-13
    • 1970-01-01
    • 2016-12-28
    • 1970-01-01
    • 2014-04-03
    • 2012-09-21
    • 1970-01-01
    • 1970-01-01
    • 2012-09-16
    相关资源
    最近更新 更多