MST

星途 面试题库

面试题:C++初始化成员列表在模板与复杂类型嵌套场景中的运用

设计一个模板类`Matrix`,用于表示二维矩阵。`Matrix`类包含一个嵌套的`std::vector<std::vector<T>>`类型的成员变量来存储矩阵元素(`T`为模板参数),以及一个`int`类型的成员变量`size`表示矩阵的维度。要求使用初始化成员列表在构造函数中初始化这些成员变量,同时要考虑到不同类型`T`在初始化时可能遇到的问题(例如自定义类型需要合适的构造函数)。编写完整的模板类`Matrix`代码,并说明在这种复杂模板与嵌套类型场景下,初始化成员列表的最佳实践和潜在陷阱。
30.1万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
#include <iostream>
#include <vector>

template<typename T>
class Matrix {
private:
    std::vector<std::vector<T>> data;
    int size;
public:
    // 使用初始化成员列表的构造函数
    Matrix(int s) : size(s), data(s, std::vector<T>(s)) {}

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

    // 获取矩阵元素(常量版本)
    const T& operator()(int i, int j) const {
        return data[i][j];
    }
};

初始化成员列表最佳实践

  1. 顺序很重要:成员变量应按照它们在类中声明的顺序在初始化列表中进行初始化。如果初始化顺序与声明顺序不同,可能会导致未定义行为,特别是当一个成员变量的初始化依赖于另一个成员变量时。例如,如果先初始化data再初始化sizedata的初始化可能会使用未初始化的size值。
  2. 类型匹配:确保初始化表达式的类型与成员变量的类型相匹配。对于模板类型T,需要保证T类型有合适的默认构造函数或者在初始化时能够提供正确的初始化参数。如果T是自定义类型且没有默认构造函数,需要在初始化列表中显式调用合适的构造函数。

潜在陷阱

  1. 循环依赖:避免成员变量之间产生循环依赖。例如,如果成员A的初始化依赖于成员B,而成员B的初始化又依赖于成员A,会导致未定义行为。
  2. 未初始化的成员:确保所有成员变量都在初始化列表中被初始化。遗漏某个成员变量的初始化会导致该成员变量使用默认初始化,对于一些类型(如std::vector),默认初始化可能与预期不符。
  3. 异常安全:如果在初始化过程中可能抛出异常,要确保类处于一个一致的状态。例如,如果data的初始化抛出异常,size可能已经被设置为一个非零值,这可能会导致类处于一个不一致的状态。可以考虑使用智能指针或者其他异常安全的设计模式来处理这种情况。