从 C++ 中的函数 return 继承 class 的最佳方法

Best way to return an inherited class from a function in c++

我正在寻求有关如何继续使用 C++ 构建的 class 层次结构的建议。

基础 class 是矩阵:

class Matrix
{
protected:

    int rows;
    int columns;
    double* values;

public:

\lots of stuff goes here. bla di bla di bla.

    virtual Matrix operator+(const Matrix& addend) const;

\etc.
}

Squarematrix 继承自 Matrix

class Squarematrix : public Matrix
{
public:

    Squarematrix operator+(const Squarematrix& addend) const;

}

运算符+ return分别是矩阵或方阵。由于 operator+ 是一个虚函数,因此无法编译,因为它必须在所有 class 中具有相同的 return 类型。

那么我有什么选择?

我可以使用普通函数而不是虚拟函数。这有点烦人,但在大多数情况下不会造成问题。

我可以在所有情况下 return 一个矩阵。这基本上会使我的方阵 class 使用起来非常痛苦,因为我必须不断地从矩阵向下转换到方阵。

我可以 return 对方阵的引用。然后矩阵必须存储在堆上,并且无法确保它被安全删除。特别是如果我做这样的事情:

squarematrix a=b+(c+d);

(c+d) 将存储在堆上并且没有指向它的指针,因此将被泄漏。

有什么方法可以保留虚函数并且仍然具有不同的 return 类型吗?

在这种情况下你有什么建议?

感谢您的帮助。期待您的来信。

我会推荐:

  1. 移除Squarematrix.
  2. Matrix中添加一个构造函数来构造一个方阵。
  3. 如果了解矩阵是否为方阵对您的应用有帮助,请在Matrix中添加一个成员函数来回答该查询。

class Matrix
{
   public:

      Matrix(int r);        // Construct a square matrix.
      Matrix(int r, int c); // Construct a rectangular matrix.

      bool isSquareMatrix() const { return (rows == columns); }

      Matrix operator+(const Matrix& addend) const;

   private:

      int rows;
      int columns;
      double* values;

}

这称为 return 类型协方差 (https://en.wikipedia.org/wiki/Covariant_return_type)。

旧的编译器不支持它,但现在很多编译器都支持它。例如,我的代码在 Visual Studio 2017 中编译良好。这是一篇关于它在 c++ 中的使用和限制的文章:https://aycchen.wordpress.com/2009/08/17/covariant-return-type-in-cpp/

它在 C# 中尚不支持,但正在考虑在未来的版本中使用。参见 https://github.com/dotnet/csharplang/issues/49

Java 的较新版本也支持它。参见 https://blogs.oracle.com/sundararajan/covariant-return-types-in-java

除了实现问题,据我所知,没有理由不将其添加到多态语言中。我不相信它会导致错误,尽管由于 Java 中的不完善实现,它可能会导致错误 - 请参阅 https://dzone.com/articles/covariant-return-type-abyssal.