SquareMatrix 的 ADT 构造函数有什么问题?

What's wrong with ADT constructor for SquareMatrix?

本文关键字:什么 问题 构造函数 ADT SquareMatrix      更新时间:2023-10-16

我为了创建一个方阵ADT对象而编写的这个项目的构造函数(不是默认构造函数)有问题。我已经将问题追溯到构造函数,但我无法弄清楚它出了什么问题,每次我尝试在 main .cpp 中运行测试时都会崩溃。

我通常会收到一个错误,上面写着"线程 1:EXC_BAD_ACCESS:..."控制台通常说"(11db)">

有没有人对可能导致所有问题的原因有任何想法?

这是头文件:

#include <iostream>
#include <vector>
using namespace std;
#ifndef SquareMatrix_h
#define SquareMatrix_h
class SquareMatrix {
private:
vector<vector<double>> numMatrix;
public:
SquareMatrix();
SquareMatrix(vector<vector<double>>& v2d);
double getValue(int x, int y);
void setValue(int x, int y, double value);
friend SquareMatrix operator * (SquareMatrix m1, SquareMatrix m2);
friend SquareMatrix operator - (SquareMatrix m1, SquareMatrix m2);
friend ostream& operator <<(ostream &out, SquareMatrix m);
};
#endif /* SquareMatrix_h */

这是我的SquareMatrix.cpp文件:(我认为不起作用的构造函数是代码中的第二个函数:SquareMatrix::SquareMatrix(vector>& v2d) {...)

#include "SquareMatrix.h"
#include <iostream>
using namespace std;
SquareMatrix::SquareMatrix() {
numMatrix.clear();
for(int i = 0; i < 10; i++) {
vector<double> initial;
for(int j = 0; j < 10; j++) {
initial.push_back(0.0);
}
numMatrix.push_back(initial);
}
}
SquareMatrix::SquareMatrix(vector<vector<double>>& v2d) {
bool flagSize = true;
for(int i = 0; i < v2d.size(); i++) {
if(v2d[i].size() != v2d.size()) {
flagSize = false;
break;
}
}
if(flagSize) {
numMatrix.clear();
for(int i = 0; i < v2d.size(); i++) {
vector<double> initial;
for(int j = 0; j < v2d[i].size(); i++) {
initial.push_back(v2d[i][j]);
}
numMatrix.push_back(initial);
}
} else {
numMatrix.clear();
for(int i = 0; i < 10; i++) {
vector<double> initial;
for(int j = 0; j < 10; j++) {
initial.push_back(0.0);
}
numMatrix.push_back(initial);
}
}
}
double SquareMatrix::getValue(int x, int y) {
if((x < numMatrix.size()) && (y < numMatrix.size()) && (x >= 0) && (y >= 0)) {
return numMatrix[x][y];
}
return 0;
}
void SquareMatrix::setValue(int x, int y, double value) {
if((x < numMatrix.size()) && (y < numMatrix.size()) && (x >= 0) && (y >= 0)) {
numMatrix[x][y] = value;
}
}
SquareMatrix operator * (SquareMatrix m1, SquareMatrix m2) {
if(m1.numMatrix.size() == m2.numMatrix.size()) {
vector<vector<double>> result;
for(int i = 0; i < m1.numMatrix.size(); i++) {
vector<double> initial;
for(int j = 0; j < m1.numMatrix.size(); j++) {
initial.push_back(0);
}
result.push_back(initial);
}
for(int i = 0; i < m1.numMatrix.size(); i++) {
for(int j = 0; j < m1.numMatrix.size(); j++) {
result[i][j] = 0;
for (int a = 0; a < m1.numMatrix.size(); a++) {
result[i][j] += m1.numMatrix[i][a] + m2.numMatrix[a][j];
}
}
}
return SquareMatrix(result);
}
return SquareMatrix();
}
SquareMatrix operator - (SquareMatrix m1, SquareMatrix m2) {
if(m1.numMatrix.size() == m2.numMatrix.size()) {
vector<vector<double>> result;
for(int i = 0; i < m1.numMatrix.size(); i++) {
vector<double> initial;
for(int j = 0; j < m1.numMatrix[i].size(); j++) {
double pushNum = (m1.getValue(i,j) - m2.getValue(i,j));
initial.push_back(pushNum);
} 
result.push_back(initial);
}
return SquareMatrix(result);
}
return SquareMatrix();
}
ostream& operator << (ostream &out, SquareMatrix m) {
out << "(";
for (int i = 0; i < m.numMatrix.size(); i++) {
for (int j = 0; j < m.numMatrix.size(); j++) {
out << " " << m.numMatrix[i][j];
if(j != (m.numMatrix.size() - 1)) {
out << ", ";
}
}
}
out << ")";
return out;
}

然后这是我用来测试SquareMatrix ADT对象的主要.cpp:

#include "SquareMatrix.h"
#include <iostream>
#include <random>
#include <ctime>
#include <vector>
using namespace std;
int main() {
srand(time(NULL));
vector<vector<double>> m1;
vector<vector<double>> m2;
int size = 0;
cout << "Enter the size of the Square Matrix: ";
cin >> size;
for (int i = 0; i < size; i++) {
vector<double> in1;
vector<double> in2;
for (int j = 0; j < size; j++) {
in1.push_back(rand() % 100);
in2.push_back(rand() % 100);
}
m1.push_back(in1);
m2.push_back(in2);
}
SquareMatrix res1 = SquareMatrix(m1);
SquareMatrix res2 = SquareMatrix(m2);
cout<< "nMatrix 1: " << endl;
cout << res1 << endl;
cout<< "nMatrix 2: " << endl;
cout << res2 << endl;
SquareMatrix mult = res1*res2;
cout << "nMatrix1 * Matrix 2: " << endl;
cout << mult << endl;
SquareMatrix min1_2 = res1 - res2;
cout << "Matrix1 - Matrix 2: " << endl;
cout << min1_2 << endl;
SquareMatrix min2_1 = res2 - res1;
cout << "Matrix2 - Matrix 1: " << endl;
cout << min2_1 << endl;
return 0;
}

您能提供的任何帮助将不胜感激。 :)

正如评论中指出的,您的问题是嵌套循环中的一个简单拼写错误。但是,我想添加一些建议,使您的代码不易出错(并且更具可读性)。

首先,在遍历向量的所有元素时,除非你需要其他内容的索引,否则你应该使用基于范围的for循环。在代码中,可以将方形大小检查替换为以下内容:

for (const vector<double>& vec: v2d){
if (vec.size() != v2d.size()){
flagSize = false;
break;
}
}

这样可以更清楚地表达您的意图,更重要的是,可以防止您意外读取/写入超出向量范围的位置(意外键入<=,而不仅仅是发生在我们最好的人身上<)。

其次,两个嵌套循环(包含您的错误)可以用简单的复制赋值(numMatrix = v2d;引用)替换。同样,这除了短得多之外,还表达了您的意图。无需重新发明具有此类功能的轮子。

周围的 if 语句的 else-分支的内容也可以替换为调用 assign (页面上列出的第一个重载,使用 likenumMatrix.assign(10, vector<double>(10, 0.0)))。像以前一样,更清晰地表达意图并避免索引错误。

最后,此构造函数中的参数可以是 const 引用,而不是普通引用,因为您不会以任何方式更改其内容(并且,鉴于此,它应该是 const)。

您可能想知道为什么"意图表达"是相关的,或者在这种情况下它甚至意味着什么。从本质上讲,这一切都是为了让你试图做的事情对任何读者来说都是显而易见的。这在具有许多贡献者的大型项目中更为重要,但即使在调试像这样的小型应用程序时也很有帮助。你似乎还在学习,但我坚信从一开始就记住这是一件好事。毕竟,其中许多更改也使代码更简短,使您在遇到问题时更容易为您提供帮助。

我意识到这在一定程度上离开了原始问题的范围,但我希望您仍然觉得这有所帮助。