Passing data from constructor to member function

Viewed 79

I am trying to write a class that do matrix multiplication. The class matrix declared like below:

class matrix
{
public:
    vector<vector<int> > M;

    matrix();
    matrix(int m, int n);
    matrix(vector<vector<int> > &m);
    matrix Mul(matrix m1);
    void Inverse();
    bool SquareMatrix();
    void GetDet();
    int Det(vector<vector<int> > &m);
    void Print();
};

I initialize and enter the elements of the matrix M in this constructor:

matrix::matrix(int m, int n)
{
    vector<vector<int> > M(m, vector<int>(n, 0));
    cout << "Enter the elements: " << endl;

    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
        {
            cin >> M[i][j];
        }
    }
}

However, the member function "Mul" do not receive the data I input through the constructor.

matrix matrix::Mul(matrix m1)
{
    int **ppInt;
    ppInt = new int *[M.size()];
    for (int i = 0; i < M.size(); i++)
    {
        ppInt[i] = new int[m1.M[0].size()];
    }

    if (M[0].size() != m1.M.size())
    {
        cout << "Cannot do multiplication!" << endl;
        return matrix();
    }
    else
    {
        for (int i = 0; i < M.size(); i++)
        {
            for (int j = 0; j < m1.M[0].size(); j++)
            {
                int ele_buf = 0;
                for (int k = 0; k < M[0].size(); k++)
                {
                    ele_buf += M[i][k] * m1.M[k][j];
                }
                ppInt[i][j] = ele_buf;
            }
        }
    }
    int d1 = M.size(), d2 = m1.M[0].size();

    for (int i = 0; i < M.size(); i++)
    {
        M[i].clear();
    }
    M.clear();

    for (int i = 0; i < d1; i++)
    {
        for (int j = 0; j < d2; j++)
        {
            M[i][j] = ppInt[i][j];
        }
    }
}

How can I fix it?

Please let me know if my problem is not clear enough.

2 Answers

I initialize and enter the elements of the matrix M in this constructor!

No! You are working with a local M, not with the member M.

In the constructor

matrix::matrix(int m, int n)
{
    vector<vector<int> > M(m, vector<int>(n, 0));  // local to the constructor only!
    // .........
}

the M is local to the scope of the constructor, which shadows the member you defined with the same name M. Therefore it (i.e the one in the constructor) will be destroyed after the constructor scope. In effect, the member M will never get initialized.


How can I fix it?

In order to fix, you might want to std::vector::resize the member M

matrix(int m, int n)
{
   M.resize(m, vector<int>(n, 0)); // resize M with `m` and `n`
   std::cout << "Enter the elements: " << std::endl;

   for (std::vector<int>& row : M)
      for (int& ele : row)
         std::cin >> ele;  // fill the elements
}

I initialize and enter the elements of the matrix M in this constructor:

No you don't. You are initializing a vector called M that shadows the member with the same name. The M in the constructor is a different vector that is local to the constructor.

To initialize members, use the initializer list:

matrix::matrix(int m, int n) : M(m, vector<int>(n, 0)) {
cout << "Enter the elements: " << endl;

    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
        {
            cin >> M[i][j];
        }
    }
}
Related