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

时间:2017-03-20 20:37:43

标签: c++ c++11 constructor overloading

我正在编写的这个项目是为了创建一个Square Matrix 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&gt;&amp; 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对象的main.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;
}

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

1 个答案:

答案 0 :(得分:0)

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

首先,当迭代向量的所有元素时,除非你需要其他东西的索引,否则你应该使用a range-based for-loop。在您的代码中,您可以使用以下内容替换方形大小的检查:

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

这更清楚地表达了您的意图,更重要的是,可以防止您意外地从您的矢量界限中读取/写入某个位置(意外键入&lt; =而不仅仅是&lt;发生在我们最好的人身上) )。

其次,两个嵌套循环(包含您的错误)可以用简单的副本分配(numMatrix = v2d; reference)替换。同样,这表达了你的意图,除了缩短了很多。无需像这些功能一样重新发明轮子。

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

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

您可能想知道为什么“意图表达”是相关的,或者在这种情况下它甚至意味着什么。从本质上讲,它是关于为任何读者立即制作你想要做的事情。这在具有许多贡献者的大型项目中更为重要,但即使在调试像这样的小应用程序时它也很有用。你似乎还在学习,但我坚信从一开始就要记住这件事是件好事。毕竟,许多这些更改也会使代码更简单,如果您遇到问题,其他人也可以更轻松地帮助您。

我意识到这在某种程度上留下了原始问题的范围,但我希望你能发现它仍然有用。