RAII and dynamic memory in classes (part 2)

This lesson contains approximately 18 minutes of video content.

Our VectorInt implementation continued

Activity: Matrix resize

Graded Playground Autograder

Activity Prompt:

In this activity, you will finish a partially complete implementation of a MatrixInt class. The MatrixInt should allocate and deallocate a non-empty rows_ x cols_ array of ints in its constructor and destructor, respectively. You will also have to implement the Resize method, which will resize the non-empty 2D array to the dimensions specified. If the dimensions become smaller, values at the right and/or bottom edges will not be retained. If the dimensions become bigger, new values at the right and/or bottom will be initialized to zero.

Resize example:
{{1, 2, 3},
{4, 5, 6},
{7, 8, 9}}


After Resize(2,4) is called:
{{1, 2, 3, 0},
{4, 5, 6, 0}}
Function Description
MatrixInt(unsigned int rows, unsigned int cols) Constructor. Should dynamically allocate the non-empty 2D array of ints matrix_ with rows rows and cols cols, initialized to be all zeros.

If rows or cols are invalid, throw a std::invalid_argument exception.
~MatrixInt() Destructor. Should deallocate matrix_ completely.
void Resize(unsigned int new_rows, unsigned int new_cols) Resizes the matrix according to the specifications above.

If new_rows or new_cols is invalid, throw a std::invalid_argument exception.
int Get(unsigned int row, unsigned int col) Provided: returns the value of the matrix at (row, col).
void Set(unsigned int row, unsigned int col, int new_val) Provided: sets the value of the matrix at (row, col) to new_val.
friend std::ostream& operator<<(std::ostream& os, const MatrixInt& matrix) Provided: prints the matrix to os.
Data Member Description
int** matrix_ Pointer to the non-empty 2D matrix.
unsigned int rows_ Amount of rows (height).
unsigned int cols_ Amount of cols (width)
#include "matrix_int.hpp" int main() { MatrixInt matrix(3, 3); matrix.Set(0,0,1); matrix.Set(0,1,2); matrix.Set(0,2,3); matrix.Set(1,0,4); matrix.Set(1,1,5); matrix.Set(1,2,6); matrix.Set(2,0,7); matrix.Set(2,1,8); matrix.Set(2,2,9); std::cout << matrix << std::endl; // matrix.Resize(2,4); // std::cout << matrix << std::endl; }
#ifndef MATRIX_INT_HPP #define MATRIX_INT_HPP #include <iostream> #include <stdexcept> class MatrixInt { public: MatrixInt(unsigned int rows, unsigned int cols); ~MatrixInt(); void Resize(unsigned int new_rows, unsigned int new_cols); int Get(unsigned int row, unsigned int col); void Set(unsigned int row, unsigned int col, int new_val); friend std::ostream& operator<<(std::ostream& os, const MatrixInt& matrix); private: int** matrix_; unsigned int rows_; unsigned int cols_; }; std::ostream& operator<<(std::ostream& os, const MatrixInt& matrix); #endif
#include "matrix_int.hpp" MatrixInt::MatrixInt(unsigned int rows, unsigned int cols) : rows_{rows}, cols_{cols}, matrix_{nullptr} { // TODO } MatrixInt::~MatrixInt() { // TODO } void MatrixInt::Resize(unsigned int new_rows, unsigned int new_cols) { // TODO } // PROVIDED - DO NOT MODIFY int MatrixInt::Get(unsigned int row, unsigned int col) { if (row >= rows_ || col >= cols_ || row < 0 || col < 0) { throw std::invalid_argument("Invalid idx"); } return matrix_[row][col]; } void MatrixInt::Set(unsigned int row, unsigned int col, int new_val) { if (row >= rows_ || col >= cols_ || row < 0 || col < 0) { throw std::invalid_argument("Invalid idx"); } matrix_[row][col] = new_val; } std::ostream& operator<<(std::ostream& os, const MatrixInt& matrix) { for (unsigned int i = 0; i < matrix.rows_; ++i) { for (unsigned int j = 0; j < matrix.cols_; ++j) { os << matrix.matrix_[i][j] << "\t"; } os << std::endl; } return os; }