面试题答案
一键面试成员函数重载
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 operator+(const Matrix& other) const {
Matrix result(rows, cols);
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
result.data[i][j] = data[i][j] + other.data[i][j];
}
}
return result;
}
};
友元函数重载
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;
}
friend Matrix operator+(const Matrix& a, const Matrix& b);
};
Matrix operator+(const Matrix& a, const Matrix& b) {
Matrix result(a.rows, a.cols);
for (int i = 0; i < a.rows; ++i) {
for (int j = 0; j < a.cols; ++j) {
result.data[i][j] = a.data[i][j] + b.data[i][j];
}
}
return result;
}
普通函数重载
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;
}
int get(int i, int j) const { return data[i][j]; }
};
Matrix operator+(const Matrix& a, const Matrix& b) {
Matrix result(a.getRows(), a.getCols());
for (int i = 0; i < a.getRows(); ++i) {
for (int j = 0; j < a.getCols(); ++j) {
result.data[i][j] = a.get(i, j) + b.get(i, j);
}
}
return result;
}
性能分析
在频繁进行矩阵加法运算时,成员函数重载和友元函数重载的性能基本相同且相对较好。因为这两种方式都可以直接访问类的私有成员,避免了通过接口函数(如普通函数重载中的get
函数)间接访问带来的额外开销。普通函数重载性能较差,因为每次访问矩阵元素都需要调用get
函数,增加了函数调用的开销。
性能较差方式的优化
- 内联函数:将
get
函数声明为inline
,这样在编译时函数调用会被替换为函数体的代码,减少函数调用开销。 - 直接访问成员:如果可能,修改普通函数重载的实现,让普通函数也能直接访问矩阵类的私有成员,这样就和成员函数、友元函数一样高效。可以通过将普通函数声明为类的友元来实现直接访问私有成员。
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;
}
friend Matrix operator+(const Matrix& a, const Matrix& b);
};
Matrix operator+(const Matrix& a, const Matrix& b) {
Matrix result(a.rows, a.cols);
for (int i = 0; i < a.rows; ++i) {
for (int j = 0; j < a.cols; ++j) {
result.data[i][j] = a.data[i][j] + b.data[i][j];
}
}
return result;
}