面试题答案
一键面试#include <iostream>
class Matrix {
private:
int** data;
int rows;
int cols;
public:
// 构造函数
Matrix(int r, int c) : rows(r), cols(c) {
data = new int* [rows];
for (int i = 0; i < rows; ++i) {
data[i] = new int[cols];
for (int j = 0; j < cols; ++j) {
data[i][j] = 0;
}
}
}
// 析构函数
~Matrix() {
for (int i = 0; i < rows; ++i) {
delete[] data[i];
}
delete[] data;
}
// 拷贝构造函数
Matrix(const Matrix& other) : rows(other.rows), cols(other.cols) {
data = new int* [rows];
for (int i = 0; i < rows; ++i) {
data[i] = new int[cols];
for (int j = 0; j < cols; ++j) {
data[i][j] = other.data[i][j];
}
}
}
// 打印矩阵的函数
void printMatrix() const {
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
std::cout << data[i][j] << " ";
}
std::cout << std::endl;
}
}
};
函数协同工作原理
- 构造函数:在
Matrix
对象实例化时,构造函数根据传入的行数rows
和列数cols
分配内存。首先为指针数组data
分配内存,该数组的每个元素是指向int
数组(对应矩阵的每一行)的指针。然后为每一行分配内存,并初始化每个元素为0。这样就完成了矩阵内存的分配。 - 析构函数:当
Matrix
对象生命周期结束时,析构函数被调用。它首先释放每一行的内存(通过delete[] data[i]
),然后释放data
指针数组的内存(通过delete[] data
)。确保了在对象销毁时所有分配的内存都被正确释放,避免内存泄漏。 - 拷贝构造函数:当通过拷贝已有的
Matrix
对象来创建新对象时,拷贝构造函数被调用。它首先为新对象分配与原对象相同大小的内存,然后将原对象的每个元素复制到新对象中。这样新对象有自己独立的内存空间,不会与原对象共享内存,避免了浅拷贝带来的问题(如一块内存被多次释放导致程序崩溃)。
通过这三个函数的协同工作,在实例化多个Matrix
对象时,可以有效地管理内存,确保内存的正确分配与释放,避免内存泄漏。