...
/The Copy Constructor, operator=(), and Destructor
The Copy Constructor, operator=(), and Destructor
Learn about the importance of copy constructors and destructors, along with their implementation.
The matrix case study: Adding the copy constructor
Let’s implement the copy constructor using the deep copy for our Matrix class. We’ll add a parameterized constructor that receives a Matrix object as the parameter. Let’s add the signature in the Matrix.h file.
Matrix(const Matrix& M);
Let’s add the definition in the Matrix.cpp file.
Matrix::Matrix(const Matrix& M){this->Vs = nullptr;this->Allocate2D(M.rows,M.cols); // Allocates new memory for the matrix according to the given number of rows and columnsthis->copyValues(M); // Coppies the object in the newly allocated space}
Here, we can see that we allocate memory using the
Allocate2D()function and copy the values usingcopyValues()function in the newly allocated memory.
Overloading the assignment operator (=)
Let’s overload the assignment operator (=) by implementing the operator=() function for the Matrix class.
Matrix& Matrix::operator=(const Matrix& M){if (this == &M)return *this;if(this->Vs!=nullptr)this->DeleteMatrix();this->Allocate2D(M.rows, M.cols);this->copyValues(M);return *this;}
Why do we need a destructor in the Matrix class?
The destructor is needed in this context to ensure proper cleanup and deallocation of resources held by a Matrix object. In particular, the destructor is responsible for releasing dynamically allocated memory used by a Matrix object, such as the memory for storing matrix elements and the memory for the row pointers. By defining a destructor, we can guarantee that the Matrix object’s resources are properly released when it goes out of scope or is explicitly destroyed, preventing memory leaks and freeing system resources.
Matrix::~Matrix(){this->DeleteMatrix();}void Matrix::DeleteMatrix(){for (int i = 0; i < this->rows; i++)delete[]this->Vs[i];delete[]this->Vs;this->Vs = nullptr;this->rows = 0;this->cols = 0;}
The above code snippet shows the destructor
Matrix::~Matrix()and the accompanying member functionMatrix::DeleteMatrix()in theMatrixclass. The destructor is responsible for ensuring a proper cleanup of theMatrixobject. It calls theDeleteMatrix()function, which iterates through each row of the matrix and deletes the dynamically allocated memory for the elements in that row. It then deletes the memory for the row pointers, sets the matrix pointer tonullptr, and updates the number of rows and columns to0, indicating an empty matrix. By callingDeleteMatrix()in the destructor, theMatrixobject is effectively cleaned up, and any dynamically allocated memory is deallocated, preventing memory leaks and freeing system resources.
Complete basic implementation
Here’s the complete implementation of the copy constructor and overloading of the assignment (=) operator.
3 3 4 7 5 9 8 5 3 7 2
This code snippet is a program that loads matrices from a file, makes a copy of the loaded matrices, and displays the original and copied matrices. The
LoadMatrix()function reads the matrices from the file and stores them in a dynamically allocated array. In themain()function, theLoadMatrix()function is called to load the matrices. The pointerM2is then assigned the value ofM1to create a copy. Finally, the original and copied matrices are displayed.
Here’s the pictorial representation of the two matrices M1 and M2 (stored as arrays) in terms of memory.
Now that we have established the necessary foundation of loading matrices and understand copy constructors and the assignment operator, we can proceed to implement various operators on matrices. By doing so, we aim to create a comprehensive matrix calculator that can perform a wide range of operations.