如何使用静态成员函数创建矩阵,然后使用运算符重载打印该矩阵
How to use a static member function to create a matrix which can then be printed using operator overloading?
使用构造函数和运算符重载的工作原理如下,我的目标是创建一个2x4的零矩阵:
Matrix::Matrix(const int noOfRowss, const int noOfCols){
this->noOfRows=noOfRowss;
this->noOfColums=noOfCols;
data= new double[noOfRows*noOfColumns];
for(int i=0; i< noOfRows; i++){
for(int j=0; j<noOfColumns; j++){
int index = i*noOfColumns + j;
data[index]=0;
}
}
}
std::ostream& operator<<(std::ostream& output, const Matrix& rhs){
for(int i=0; i< rhs.noOfRows; i++){
for(int j=0; j<rhs.noOfColumns; j++){
int index = i*rhs.noOfColumns + j;
output<<rhs.data[index]<< "t";
}
output<<std::endl;
}
return output;
}
然而,当我尝试使用静态成员函数时,我会遇到以下代码的分段错误(请参阅下面的测试文件中的实现):
Matrix Matrix::Zeros(const int noOfRows, const int noOfCols){
Matrix out;
for(int i=0; i< noOfRows; i++){
for(int j=0; j<noOfCols; j++){
int index = i*noOfCols + j;
out.data[index]=0;
}
}
}
我不确定我是否正确地实现了静态成员函数,我的问题是在我的头函数中,我需要使用以下变量:
int noOfRows;
int noOfColumns;
double *data;
int GetIndex(const int rowIdx, const int columnIdx) const;
在我的测试文件中,我想实现这个静态成员函数,如下所示:
Matrix matrix = Matrix::Zeros(2,4);
cout<<matrix<<endl;
我需要保留数据变量的原因是,它可以用于运算符<lt;重载函数,就像它以前为构造函数所做的那样。然而,在我的静态成员函数中尝试了几种不同的变体后,我没有像以前那样容易地将矩阵存储在数据变量中。有人有什么建议吗?
因此,我看到您的静态函数显然首先做到了这一点。
Matrix output;
但是,您展示的构造函数代码有两个参数,即行数和列数。
由此,我必须得出结论,您还必须有一个默认构造函数,该构造函数可能会构造一个空矩阵,其中包含一个空的data
向量。
for(int i=0; i< noOfRows; i++){
for(int j=0; j<noOfCols; j++){
int index = i*noOfCols + j;
output.data[index]=0;
}
}
然后,在没有有效初始化的data
成员的情况下,尝试初始化默认构造矩阵的内容。
这不会有好的结局。。。
附言,你可能也想读一读:RAII。我怀疑你们班在这方面也会有相关的问题。与其使用double *data
成员,std::vector<double>
将更好地工作,并且很可能避免该领域的一系列陷阱。
您需要像这样psecify out
对象的大小(否则,您将在边界外填充out.data
):
Matrix Matrix::Zeros(const int noOfRows, const int noOfCols){
Matrix out(noOfRows*noOfCols); // changed here
for(int i=0; i< noOfRows; i++){
for(int j=0; j<noOfCols; j++){
int index = i*noOfCols + j;
out.data[index]=0;
}
}
}
如果这样做,至少遵循三条规则会更安全,因为使用Matrix::Zeros
很可能会在代码中通过复制进行构造或通过复制进行赋值(如果定义不正确,会导致更多的segfault,使用默认实现的编译器会导致double*
指针混乱)。正如Sam Varshavchik所指出的,使用std::vector<double>
而不是double*
将使这些默认实现在您的情况下运行良好。
但是,对于你试图解决的特定问题,我建议你简单地修改你的构造函数,使其能够决定默认的矩阵内容,这可能更容易:
Matrix::Matrix(const int noOfRowss, const int noOfCols, double defaultValue)
{
this->noOfRows=noOfRowss;
this->noOfColums=noOfCols;
data= new double[noOfRows*noOfColumns];
for(int i=0; i< noOfRows; i++){
for(int j=0; j<noOfColumns; j++){
int index = i*noOfColumns + j;
data[index]=defaultValue;
}
}
}
在头文件中,可以有:
class Matrix
{
public:
Matrix(const int noOfRowss, const int noOfCols, double defaultValue = 0);
...
};
然后:
std::cout << Matrix(4,2) << std::endl; // displays a 4x2 matrix filled with zeros
std::cout << Matrix(4,2,1) << std::endl; // displays a 4x2 matrix filled with ones
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- <T> 通过模板化运算符重载将 std::complex 乘以双倍
- C++20概念:需要运算符重载
- 使用赋值运算符重载从类中返回jobject
- 在运算符重载定义中使用成员函数(const错误)
- 字节到位运算符重载C++
- 为什么在运算符重载时需要参考?
- 类中 c++ 的运算符 + 重载
- 算术复合运算符重载为非成员
- 运算符重载 (+),用于添加两个具有 C++ 的数组
- 交换运算符 + 重载会导致无限递归
- 如何理解新的运算符重载?
- 向量保持复数的运算符重载
- 如何创建运算符重载?
- 链接列表运算符重载没有打印出我想要的内容
- C++:需要帮助了解运算符重载错误
- 使用模板化运算符重载 XOR 运算符失败
- 如何确保接受的C++模板类型使运算符重载?
- 运算符重载使用运算符+添加类模板