#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];
}
};
初始化成员列表最佳实践
- 顺序很重要:成员变量应按照它们在类中声明的顺序在初始化列表中进行初始化。如果初始化顺序与声明顺序不同,可能会导致未定义行为,特别是当一个成员变量的初始化依赖于另一个成员变量时。例如,如果先初始化
data
再初始化size
,data
的初始化可能会使用未初始化的size
值。
- 类型匹配:确保初始化表达式的类型与成员变量的类型相匹配。对于模板类型
T
,需要保证T
类型有合适的默认构造函数或者在初始化时能够提供正确的初始化参数。如果T
是自定义类型且没有默认构造函数,需要在初始化列表中显式调用合适的构造函数。
潜在陷阱
- 循环依赖:避免成员变量之间产生循环依赖。例如,如果成员
A
的初始化依赖于成员B
,而成员B
的初始化又依赖于成员A
,会导致未定义行为。
- 未初始化的成员:确保所有成员变量都在初始化列表中被初始化。遗漏某个成员变量的初始化会导致该成员变量使用默认初始化,对于一些类型(如
std::vector
),默认初始化可能与预期不符。
- 异常安全:如果在初始化过程中可能抛出异常,要确保类处于一个一致的状态。例如,如果
data
的初始化抛出异常,size
可能已经被设置为一个非零值,这可能会导致类处于一个不一致的状态。可以考虑使用智能指针或者其他异常安全的设计模式来处理这种情况。