Learn C++ Online

RAII and dynamic memory in classes (part 2)

On this page
This lesson contains approximately 18 minutes of video content.

Our VectorInt implementation continued

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; }
> Click Run to compile and run your code.