从c+;中的函数返回继承类的最佳方法+; 我正在寻找关于如何继续使用C++中构建的类层次结构的建议。
基类是矩阵:从c+;中的函数返回继承类的最佳方法+; 我正在寻找关于如何继续使用C++中构建的类层次结构的建议。,c++,inheritance,matrix,return-type,virtual-functions,C++,Inheritance,Matrix,Return Type,Virtual Functions,基类是矩阵: 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. } 平方矩阵是从矩阵继承而来的 class Squarematrix :
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.
}
平方矩阵是从矩阵继承而来的
class Squarematrix : public Matrix
{
public:
Squarematrix operator+(const Squarematrix& addend) const;
}
运算符+分别返回矩阵或平方矩阵。因为操作符+是一个虚拟函数,所以它不会编译,因为它在所有类中必须具有相同的返回类型
那么我有什么选择呢
我可以用普通函数代替虚拟函数。这有点烦人,但在大多数情况下不会造成问题
我可以在所有情况下返回矩阵。这将基本上使我的squarematrix类成为***中的一个正确的痛苦,因为我必须不断地从一个矩阵到另一个矩阵进行向下转换
我可以返回对平方矩阵的引用。那么矩阵将不得不存储在堆上,并且无法确保其被安全删除。特别是如果我做了这样的事情:
squarematrix a=b+(c+d);
(c+d)将存储在堆上,并且没有指向它的指针,因此将被泄漏
是否有任何方法可以保留虚拟函数并仍然具有不同的返回类型
在这种情况下,你有什么建议
谢谢你的帮助。期待您的来信。我建议:
Squarematrix
矩阵中
以构造方形矩阵matrix
中添加成员函数以回答该查询这称为返回类型协方差() 旧的编译器不支持它,但现在很多编译器都支持它。例如,我的代码在Visual Studio 2017中编译得很好。下面是一篇关于它在c++中的使用和限制的文章: 它在C#中还不受支持,但正在考虑将来的版本。看 新版本的Java也支持它。看
除了实现问题,据我所知,没有理由不将其添加到多态语言中。我不相信它会导致错误,尽管由于Java中不完善的实现,它可能会导致错误。请参见。否。重写的虚拟函数必须返回相同的类型。故事结束了。在这种非常常见的设计模式中,虚拟函数将智能指针返回到基类。当类设计正确时,这一点就相当好了。@SamVarshavchik并不总是这样。协变返回类型很常见,例如在
clone()
成员函数中。请看。为什么operator+
需要是虚拟的?@Jarod42。有用的链接。这个问题一直困扰着我建立这个班级。现在我知道它叫什么了。但我看不出与这个问题有什么直接关系。这是否会降低类型安全性,因为任何只适用于平方矩阵(逆矩阵、对角化矩阵、行列式等)的函数都必须在运行时检查,而不是在编译时检查它们是否有效?@YairHalberstadt,是的,确实如此。但是,请考虑将<代码>子矩阵< /代码>作为类。为了计算矩阵*
或矩阵&
的行列式,必须检查它们的底层对象是否为子矩阵
。这将需要一个向下抛投
。这一点也不好。您可以提供一个virtual
函数来计算行列式。然而,对于一个矩形矩阵,你必须做些什么。无法回避这样一个事实:某些操作只允许用于对象的子集,您必须处理这些差异。
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;
}