从 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 类型吗?
在这种情况下你有什么建议?
感谢您的帮助。期待您的来信。
我会推荐:
- 移除
Squarematrix
.
- 在
Matrix
中添加一个构造函数来构造一个方阵。
- 如果了解矩阵是否为方阵对您的应用有帮助,请在
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.
我正在寻求有关如何继续使用 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 类型吗?
在这种情况下你有什么建议?
感谢您的帮助。期待您的来信。
我会推荐:
- 移除
Squarematrix
. - 在
Matrix
中添加一个构造函数来构造一个方阵。 - 如果了解矩阵是否为方阵对您的应用有帮助,请在
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.