1

Here's a tiny little class that's bothering me:

class matrix{
    string name;
    int rowSize, columnSize;
    // I could declare double m[100][100]; here but that would be ugly
    public:
    void createMat(){
        cout << "Enter Matrix Name:"; 
        cin >> name;
        cout << "Enter number of rows: "; 
        cin >> rowSize;
        cout << "Enter no. of columns: "; 
        cin >> columnSize; 
        double m[rowSize][columnSize]; //needs to be available to readMat()
        cout << "Enter matrix (row wise):\n";
        for(int i = 0; i < rowSize; i++){
            for(int j = 0; j < columnSize; j++){cin >> m[i][j];}
            cout<<'\n';
        }
    }
    void readMat(){
        cout << "Matrix " << name << " :\n";
        for(int i = 0 ; i < rowSize; i++){
        for(int j = 0; j < columnSize; j++){ cout << m[i][j] << ' ';}
        cout<<'\n';
        }
    }
};

How can I make m available to both createMat() and readMat() in an optimal way?

Is trying to allow the user to enter the dimensions of the matrix unnecessary?

From my point of view, I feel that me defining the maximum size of the matrix would be too limiting in case more elements are required or too much if not as many elements are required.

MisterGeeky
  • 254
  • 1
  • 8
  • 18
  • `double m[rowSize][columnSize]` Variable length arrays aren't standard C++. – Algo May 25 '14 at 15:23
  • @Algo: Are you saying that I should make them `const`? – MisterGeeky May 25 '14 at 15:30
  • 1
    The C++ standard states that array size must be a constant expression, VLA is a C99 feature not a standard C++. Even though this will compile successfully on some compilers, it's not standard. – Algo May 25 '14 at 15:35
  • 1
    http://stackoverflow.com/questions/1887097/variable-length-arrays-in-c – Algo May 25 '14 at 15:35

3 Answers3

1

You should use a dynamic-sized block of memory, and allocate it at run-time on the basis of user-input. Here, I use std::vector:

class matrix{
    std::string name;
    int rowSize, columnSize;
    std::vector<double> m;
    public:
    void createMat(){
        std::cout << "Enter Matrix Name:"; 
        std::cin >> name;
        std::cout << "Enter number of rows: "; 
        std::cin >> rowSize;
        std::cout << "Enter no. of columns: "; 
        std::cin >> columnSize; 
        m.resize(rowSize*columnSize);
        std::cout << "Enter matrix (row wise):\n";
        for(int i = 0; i < rowSize; i++){
            for(int j = 0; j < columnSize; j++){
                std::cin >> m[i*columnSize+j];
            }
            std::cout<<'\n';
        }
    }
    void readMat() {
        std::cout << "Matrix " << name << " :\n";
        for(int i = 0 ; i < rowSize; i++){
            for(int j = 0; j < columnSize; j++) {
                std::cout << m[i*columnSize+j] << ' ';
            }
            std::cout<<'\n';
        }
    }
};
Mankarse
  • 39,818
  • 11
  • 97
  • 141
  • I like your solution but O_O The program is crashing when I use this. – MisterGeeky May 25 '14 at 15:16
  • I understood the problem. I got too greedy. `int main(){ int i = 0; matrix m[i]; m[i].createMat(); m[i].readMat(); return 0; }` – MisterGeeky May 25 '14 at 15:28
  • Hahaha. It shouldn't even be possible to create the array of `matrix` with non-constexpr size. I suspect you are using `g++`, which provides runtime sized arrays as [an extension](https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html). Save yourself some trouble and disable the extensions with `-pedantic` and `-std=c++11`. – Mankarse May 25 '14 at 15:33
  • @Mankarse Wouldn't `std::vector` be easier to deal with? – Algo May 25 '14 at 15:39
  • @Algo: Yes, but it would create a ragged-array, which is not needed for a matrix, which is always guaranteed to be rectangular. – Mankarse May 25 '14 at 15:40
  • @Mankarse: Then how do you suggest I make multiple matrices? – MisterGeeky May 25 '14 at 15:43
  • @Nick: `std::vector m; m.push_back(matrix{}); m[0].createMat(); m[0].readMat();` – Mankarse May 25 '14 at 15:44
1

My answers to your questions are:

  1. Make it a class member (as obvious as it sounds, but what kind of answer did you expect?)
  2. Most likely it makes sense to allow the user to set the matrix size... but it really depends on what you need.

I would do a few things differently, in particular:

  • Instead of createMat() I would use the class constructor do carry out initialization chores (constructors exist for this very reason).

  • I would then store the elements inside a private 1D array element[rowSize*columnSize] (to be dynamically allocated inside the constructor).

  • Then I would create the void setElement(i,j) and double getElement(i,j) methods.

(Consider checking out the EIGEN library, a very slick and easy to use linear algebra library, with some Matlab-like flavor)

Emerald Weapon
  • 2,392
  • 18
  • 29
0

you need to define m as a class member and go for dynamic memory allocation.

class matrix{
    string name;
    int rowSize, columnSize;
    double **m;

    void createMat(){
       m = new double*[rowSize];
       for(int i = 0; i < rowSize; ++i)
          m[i] = new double[columnSize];

    }
 }

here's a detailed tutorial: http://www.cs.umb.edu/~mweiss/cs410_f04/ppts/cs410-7.pdf

Pavel
  • 7,436
  • 2
  • 29
  • 42
  • This is the right idea, but you shouldn't actually do it like this (as it completely lacks exception safety). – Mankarse May 25 '14 at 14:57