MST

星途 面试题库

面试题:C++ 运算符重载与模板元编程及性能优化

在C++中,结合模板元编程实现一个矩阵类 `Matrix`,并对常见的数学运算符(如 +、-、* 等)进行重载。要求考虑性能优化,例如如何避免不必要的临时对象创建,以及如何利用编译期计算提升效率。阐述设计思路并给出核心代码实现。
39.9万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 模板元编程:利用模板元编程在编译期进行一些计算,例如矩阵维度的检查、矩阵乘法的部分计算等,以减少运行时的开销。
  2. 避免临时对象
    • 对于运算符重载,尽量采用就地操作(in - place operation)的方式。例如,在 operator+= 实现中,直接修改左操作数,而不是创建一个新的矩阵。
    • 对于 operator+operator* 等返回新矩阵的操作,可以使用移动语义(C++11 引入),减少数据的拷贝。
  3. 性能优化
    • 利用编译期常量来确定矩阵的大小,这样在编译时就可以进行一些边界检查和优化。
    • 采用表达式模板(Expression Templates)技术的思想,延迟计算,进一步减少临时对象的创建。例如,对于 A + B + C 的表达式,不立即计算 A + B 的结果,而是在最终需要结果时再进行计算。

核心代码实现

#include <iostream>
#include <type_traits>

// 矩阵类模板
template <typename T, size_t rows, size_t cols>
class Matrix {
    T data[rows][cols];
public:
    // 默认构造函数
    Matrix() = default;

    // 构造函数,初始化矩阵数据
    Matrix(const T (&arr)[rows][cols]) {
        for (size_t i = 0; i < rows; ++i) {
            for (size_t j = 0; j < cols; ++j) {
                data[i][j] = arr[i][j];
            }
        }
    }

    // 获取矩阵元素
    T& operator()(size_t i, size_t j) {
        static_assert(i < rows && j < cols, "Index out of bounds");
        return data[i][j];
    }

    const T& operator()(size_t i, size_t j) const {
        static_assert(i < rows && j < cols, "Index out of bounds");
        return data[i][j];
    }

    // 矩阵加法
    Matrix<T, rows, cols>& operator+=(const Matrix<T, rows, cols>& other) {
        for (size_t i = 0; i < rows; ++i) {
            for (size_t j = 0; j < cols; ++j) {
                data[i][j] += other.data[i][j];
            }
        }
        return *this;
    }

    Matrix<T, rows, cols> operator+(const Matrix<T, rows, cols>& other) const {
        Matrix<T, rows, cols> result = *this;
        result += other;
        return result;
    }

    // 矩阵减法
    Matrix<T, rows, cols>& operator-=(const Matrix<T, rows, cols>& other) {
        for (size_t i = 0; i < rows; ++i) {
            for (size_t j = 0; j < cols; ++j) {
                data[i][j] -= other.data[i][j];
            }
        }
        return *this;
    }

    Matrix<T, rows, cols> operator-(const Matrix<T, rows, cols>& other) const {
        Matrix<T, rows, cols> result = *this;
        result -= other;
        return result;
    }

    // 矩阵乘法
    template <size_t otherCols>
    Matrix<T, rows, otherCols> operator*(const Matrix<T, cols, otherCols>& other) const {
        Matrix<T, rows, otherCols> result;
        for (size_t i = 0; i < rows; ++i) {
            for (size_t j = 0; j < otherCols; ++j) {
                T sum = 0;
                for (size_t k = 0; k < cols; ++k) {
                    sum += data[i][k] * other.data[k][j];
                }
                result(i, j) = sum;
            }
        }
        return result;
    }
};

你可以这样使用这个矩阵类:

int main() {
    int arr1[2][2] = {{1, 2}, {3, 4}};
    int arr2[2][2] = {{5, 6}, {7, 8}};

    Matrix<int, 2, 2> m1(arr1);
    Matrix<int, 2, 2> m2(arr2);

    Matrix<int, 2, 2> sum = m1 + m2;
    Matrix<int, 2, 2> diff = m1 - m2;

    int arr3[2][3] = {{1, 2, 3}, {4, 5, 6}};
    Matrix<int, 2, 3> m3(arr3);
    Matrix<int, 2, 3> product = m1 * m3;

    return 0;
}