MST
星途 面试题库

面试题:C++ 运算符重载对复杂数据结构代码可读性的影响

假设有一个自定义的矩阵类 Matrix,包含矩阵的存储和基本运算。要求通过运算符重载实现矩阵的加法、乘法运算,以此说明运算符重载如何提升矩阵操作相关代码的可读性。另外,解释在这种情况下如何处理运算符优先级和结合性对代码可读性的影响。
22.9万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

1. 矩阵类 Matrix 的运算符重载实现

#include <iostream>
#include <vector>

class Matrix {
private:
    std::vector<std::vector<int>> data;
    int rows;
    int cols;

public:
    Matrix(int r, int c) : rows(r), cols(c) {
        data.resize(rows, std::vector<int>(cols, 0));
    }

    // 获取矩阵元素
    int get(int i, int j) const {
        return data[i][j];
    }

    // 设置矩阵元素
    void set(int i, int j, int value) {
        data[i][j] = value;
    }

    // 矩阵加法运算符重载
    Matrix operator+(const Matrix& other) const {
        if (rows != other.rows || cols != other.cols) {
            throw std::invalid_argument("Matrices must have the same dimensions for addition.");
        }
        Matrix result(rows, cols);
        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < cols; ++j) {
                result.set(i, j, data[i][j] + other.data[i][j]);
            }
        }
        return result;
    }

    // 矩阵乘法运算符重载
    Matrix operator*(const Matrix& other) const {
        if (cols != other.rows) {
            throw std::invalid_argument("Number of columns in the first matrix must be equal to the number of rows in the second matrix for multiplication.");
        }
        Matrix result(rows, other.cols);
        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < other.cols; ++j) {
                int sum = 0;
                for (int k = 0; k < cols; ++k) {
                    sum += data[i][k] * other.data[k][j];
                }
                result.set(i, j, sum);
            }
        }
        return result;
    }

    // 打印矩阵
    void print() const {
        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < cols; ++j) {
                std::cout << data[i][j] << " ";
            }
            std::cout << std::endl;
        }
    }
};

2. 说明运算符重载提升代码可读性

使用运算符重载后,矩阵的加法和乘法操作变得更加直观。例如:

int main() {
    Matrix a(2, 2);
    a.set(0, 0, 1);
    a.set(0, 1, 2);
    a.set(1, 0, 3);
    a.set(1, 1, 4);

    Matrix b(2, 2);
    b.set(0, 0, 5);
    b.set(0, 1, 6);
    b.set(1, 0, 7);
    b.set(1, 1, 8);

    Matrix sum = a + b;
    Matrix product = a * b;

    std::cout << "Sum of matrices:" << std::endl;
    sum.print();

    std::cout << "Product of matrices:" << std::endl;
    product.print();

    return 0;
}

在上述代码中,a + ba * b 这样的表达式直接明了,就像我们在数学中书写矩阵运算一样,大大提升了代码的可读性。相比不使用运算符重载,使用单独的函数如 addMatrices(a, b)multiplyMatrices(a, b),运算符重载的方式更加简洁和直观。

3. 处理运算符优先级和结合性对代码可读性的影响

  • 优先级:在 C++ 中,乘法运算符 * 的优先级高于加法运算符 +,这与数学中的运算优先级一致。例如,表达式 a * b + c 会先计算 a * b,再将结果与 c 相加。这种默认的优先级规则在矩阵运算中同样适用,符合我们对数学运算优先级的理解,因此不需要额外处理就可以保证代码的可读性。

  • 结合性:加法和乘法运算符都是左结合性,即 a + b + c 会被解析为 (a + b) + ca * b * c 会被解析为 (a * b) * c。在矩阵运算中,这种结合性也符合我们对数学运算的习惯,不会对代码可读性造成负面影响。

但是,如果表达式中同时包含多种运算符且优先级和结合性较为复杂时,为了确保代码的可读性和正确性,可以使用括号明确运算顺序。例如,(a + b) * c 这样可以清楚地表明先进行加法运算,再进行乘法运算。这样即使在复杂的表达式中,也能让阅读代码的人清楚了解运算的先后顺序。