0

How to change from using pointer to vector inside the class

My teacher wants me to change from using a pointer to vector in order to create a 1D array matrix with a 1D vector. At first, I try by changing double *_data; to vector<double> _data; but it doesn't work since I didn't really understand the problem (._.) Here is the code #include <iostream> #include <cassert> using namespace std; class cmatrix { public: cmatrix(unsigned int numRows, unsigned int numCols) { _data = new double[numRows * numCols]; _cols = numCols; _rows = numRows; for (unsigned int i = 0; i < rows(); i = i + 1) { for (unsigned int j = 0; j < cols(); j = j + 1) { setElement(i, j, 0.0); } } } ~cmatrix() { delete[] _data; } double element(unsigned int row, unsigned int col) { assert(row < rows() && col < cols()); return _data[row * cols() + col]; } unsigned int rows() { return _rows; } unsigned int cols() { return _cols; } void setElement(unsigned int row, unsigned int col, double value) { assert(row < rows() && col < cols()); _data[row * cols() + col] = value; } private: unsigned int _cols; unsigned int _rows; double *_data; }; int main() { cmatrix m(5, 5); for (unsigned int i = 0; i < m.rows(); i = i + 1) { m.setElement(i, i, 1.0); // m._data[i * m.cols() + i] = 1.0; } for (unsigned int i = 0; i < m.rows(); i = i + 1) { for (unsigned int j = 0; j < m.cols(); j = j + 1) { cout << m.element(i, j) << " "; } cout << endl; } return 0; } Output: 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1

24th Nov 2019, 1:48 PM
Yourint
Yourint - avatar
9 Answers
+ 1
Well, lets see, first lets grab the documentation we need: The constructor of the vector: https://en.cppreference.com/w/cpp/container/vector/vector More specifically, we are interested in the 4th constructor: explicit vector( size_type count, const Allocator& alloc = Allocator() ); We don't need the allocator, since it's defaulted it becomes: explicit vector( size_type count ); The vector is created on the stack ( it manages the heap on it's own ) so we don't need the new and delete. Let's remove those. The constructor actually exists out of 2 parts. The constructor's initializer list. Which was my hint to you. The rest of the constructor's body. Which is the one you currently use. The initializer list is responsible for initializing all variables. By the time you reach the rest of the body, all variables are already initialized and everything becomes assignments. Kinda like doing. int i; i=5; We could use this to assign the vector. Inside of main it would be equivalent to: std::vector<type> v; v = std::vector<type>( size ); Which would work here as well. _data = new ... -> _data = std::vector<double>( numRows * numCols ); This would work fine. However as I previously mentioned, this is not the ideal solution. First the vector is initialized as an empty vector, then, the vector is assigned a new vector. Those are 2 operations. That's when the first part of the constructor appears, the contructor's initializer list. As the name probably tells you, you can initialize your objects here. The syntax is simple: constructor( ... ) : initializer_1, initializer_2, etc { body } Lets move all the assignments from the body to the initializer list. cmatrix( ... ) : _cols( numCols ) , _rows( numRows ) { ... } Now, that looks similar to the initializations you would probably see in main. ( just without the type ) Just remember to initialize them in the same order as you declared them. Can you add the initialization of the vector to the initialization list?
25th Nov 2019, 9:48 AM
Dennis
Dennis - avatar
+ 2
Could you post your code that uses the vector? So I can see where you go wrong. ( preferably a link to the code in the code playground ) Hint: https://en.cppreference.com/w/cpp/language/initializer_list
24th Nov 2019, 3:37 PM
Dennis
Dennis - avatar
+ 1
Why did you move the vector outside the class? You should keep it as a member. You didn't use the initializer list. I highly recommend that you use it. Try a new small project where you experiment with it if you have to, it's sometimes easier to learn something. 1. Just because it compiles doesn't make it correct. The vector should belong to the class. We can look for other problems later. 2. Since the destructor has nothing else to do, you can indeed remove it entirely.
25th Nov 2019, 5:33 PM
Dennis
Dennis - avatar
+ 1
Yes, that's good, Yourint But you can still make it better by using the constructor's initializer list that I explained earlier, it's quite an important thing to know about. Only include your link to the code next time please, no need for such a long post that consists out of code that's gonna be the same as the included link anyway. It keeps the q@a thread a bit neater. Hope your exam went well.
12th Dec 2019, 2:03 PM
Dennis
Dennis - avatar
0
Dennis I try to read and search for some simple example of using vector in class but I still not understand how to do it. So, It is almost the same as the original code. (TwT) https://code.sololearn.com/cSjoFcp4E9qN/#cpp
25th Nov 2019, 1:59 AM
Yourint
Yourint - avatar
0
I see a lot of examples in the internet using vector with class like they declare class then they declare vector in int main and I just don't understand-..-
25th Nov 2019, 2:06 AM
Yourint
Yourint - avatar
0
After I tried and read each line carefully then here is the result. Here is the code https://code.sololearn.com/cOHrr70xUV6g/#cpp #include <iostream> #include <vector> #include <cassert> using namespace std; class cmatrix { public: cmatrix(unsigned int numRows, unsigned int numCols,vector<double> &_data) { _data.resize(numRows * numCols); _cols = numCols; _rows = numRows; for (unsigned int i = 0; i < rows(); i = i + 1) { for (unsigned int j = 0; j < cols(); j = j + 1) { setElement(i, j, 0.0,_data); } } } ~cmatrix() { //delete[] _data; } double element(unsigned int row, unsigned int col,vector<double> &_data) { assert(row < rows() && col < cols()); return _data[row * cols() + col]; } unsigned int rows() { return _rows; } unsigned int cols() { return _cols; } void setElement(unsigned int row, unsigned int col, double value,vector<double> &_data) { assert(row < rows() && col < cols()); _data[row * cols() + col] = value; } private: unsigned int _cols; unsigned int _rows; }; int main() { vector<double> _data; cmatrix m(5, 5,_data); for (unsigned int i = 0; i < m.rows(); i = i + 1) { m.setElement(i, i, 1.0,_data); // m._data[i * m.cols() + i] = 1.0; } for (unsigned int i = 0; i < m.rows(); i = i + 1) { for (unsigned int j = 0; j < m.cols(); j = j + 1) { cout << m.element(i, j,_data) << " "; } cout << endl; } return 0; } #Doubt 1) Is it technically correct? like is there any wasted command or something like that(I don't know how to call it ._.) 2) If I don't need to use delete when I use vector, then I don't need to add ~cmatrix() in class right? By the way, I really appreciate your help in resolving my problem. Thanks a lot! :3
25th Nov 2019, 5:26 PM
Yourint
Yourint - avatar
0
Dennis next 2 weeks after I finished my final exam I will try it again :3
27th Nov 2019, 6:53 PM
Yourint
Yourint - avatar
0
Dennis I finally finished my examination. Continue from last time you told me, is it like this? https://code.sololearn.com/cc6L0wRhrN8B/#cpp #include <iostream> #include <vector> #include <cassert> using namespace std; class cmatrix { public: cmatrix(unsigned int numRows, unsigned int numCols) { _data.resize(numRows * numCols); _cols = numCols; _rows = numRows; for (unsigned int i = 0; i < rows(); i = i + 1) { for (unsigned int j = 0; j < cols(); j = j + 1) { setElement(i, j, 0.0); } } } double element(unsigned int row, unsigned int col) { assert(row < rows() && col < cols()); return _data[row * cols() + col]; } unsigned int rows() { return _rows; } unsigned int cols() { return _cols; } void setElement(unsigned int row, unsigned int col, double value) { assert(row < rows() && col < cols()); _data[row * cols() + col] = value; } private: unsigned int _cols; unsigned int _rows; vector <double> _data; };
12th Dec 2019, 1:27 PM
Yourint
Yourint - avatar