【问题标题】:What's wrong with ADT constructor for SquareMatrix?SquareMatrix 的 ADT 构造函数有什么问题?
【发布时间】:2017-08-12 07:34:23
【问题描述】:

我为创建方阵 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 对象的 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;
}

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

【问题讨论】:

  • 你有一个错字。将for(int j = 0; j &lt; v2d[i].size(); i++) 更改为for(int j = 0; j &lt; v2d[i].size(); j++)。增量需要为j++
  • 哦...哇。现在它可以工作了。谢谢!

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


【解决方案1】:

正如 cmets 中所指出的,您的问题是嵌套循环中的一个简单错字。不过,我想添加一些建议,以使您的代码更不容易出错(并且更具可读性)。

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

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

这更清楚地表达了您的意图,更重要的是,可以防止您意外地读取/写入超出向量范围的位置(不小心输入

其次,两个嵌套循环(包含您的错误)可以替换为简单的复制分配(numMatrix = v2dreference)。同样,这表达了您的意图,而且要短得多。无需使用这些功能重新发明轮子。

周围 if 语句的 else 分支的内容也可以替换为对 assign 的调用(页面上列出的第一个重载,使用类似于 numMatrix.assign(10, vector&lt;double&gt;(10, 0.0)))。和以前一样,更清晰地表达意图并避免索引错误。

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

您可能想知道为什么“意图表达”是相关的,或者它在这种情况下的含义。从本质上讲,这一切都是为了让任何读者都能立即看到你想要做的事情。这在有许多贡献者的大型项目中更为重要,但即使在调试像这样的小型应用程序时也很有帮助。您似乎仍在学习,但我坚信从一开始就牢记这一点是件好事。毕竟,其中许多更改还可以简化代码,让其他人在遇到问题时更容易帮助您。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多