查找矩阵实现的 [] 运算符中的设计缺陷
Finding design flaws in [] operator of a matrix implementation
在C++程序中,这里有两个运算符标题用作未显示的矩阵实现的 setter 和 getter。
double* Matrix::operator[](unsigned int row) const throw (MatrixException);
double* Matrix::operator[](unsigned int row) throw (MatrixException);
在不进一步了解上述运算符的实现的情况下,只需查看如何定义上述运算符,如果同时实现这两种方法,矩阵程序中的设计缺陷是什么。
关于 [] 运算符如何工作的说明: 矩阵设置如下:
Matrix *a = new Matrix(1,2); //matrix with one row and two columns
a[0][0] = 3.0;
a[0][1] = 2.3;
//to access a matrix value
double* b = a[0][1];
delete a;
编辑:你会在运算符定义中更改什么来修复设计缺陷?
第一个设计缺陷是使用了异常规范,在 C++11中已弃用。
第二个设计缺陷是,你可以索引行列之外,而类无法检查它。 即,
Matrix a( 1, 2 );
double b = a[0][4];
通过使用代理可以进行边界检查。
struct Matrix {
struct Column {
double operator[](unsigned int column);
};
Column operator[](unsigned int row);
};
最后,你的例子完全是假的。您将a
声明为指针,因此当您下标a[0][0]
时,您实际上是先下标指针,然后是行。
有一些缺陷。
最明显的一个是不必要的使用动态内存和手动内存管理。任何时候你看到delete
你几乎知道有什么不对劲,任何时候你看到new
你应该怀疑。
Matrix a(1, 2); // no new needed
a[0][0] = 3.0;
a[0][1] = 2.3;
double * b = a[0][1];
// no delete needed
这可以完全防止内存泄漏。它还避免了您包含的未实际索引数组的错误(您需要使用(*a)[0][0]
来获取第一个元素)。
其次,应返回对值的引用,而不是指针。
第三,你应该是一个返回值并将两个索引作为参数的函数,而不是重载一个operator[]
来返回一个数组,然后你必须再次取消引用。 http://www.parashift.com/c++-faq/matrix-subscript-op.html
这允许您检查边界,假设Matrix
知道自己的大小(它必须存储两个整数数据成员)。
double const & Matrix::at(size_t const row, size_t const column) const {
check_bounds(row, column);
return implementation_detail();
}
具有明显的double &
版本实现。就目前而言,您的const
成员函数版本返回double *
,而不是通过返回double const *
使const
传递(尽管引用仍然是首选)。
另一个潜在的缺陷是,像Matrix
这样的泛型类可能应该在类型上参数化:
template<typename T>
class Matrix {
public:
typedef T value_type;
...
};
因此,您的示例实际上是使用Matrix<double>
作为类型。
最后,我会对异常规范说不。它们往往会导致比修复更多的错误,这就是它们在 C++11 中被弃用的原因。
- 为什么比较运算符如此快速
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 增量运算符与后缀混淆
- 一个关于在C++中重载布尔运算符的问题
- 运算符C++ "delete []"仅删除 2 个前值
- 模板类无法识别友元运算符
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 关闭||运算符优化
- 通过继承类使用来自不同命名空间的运算符
- C++Cast运算符过载
- 如何使用AngelScript注册SFML Vector2运算符
- 重载元组索引运算符-C++
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 布尔比较运算符是如何在C++中工作的
- 重载运算符new[]的行为取决于析构函数
- 查找矩阵实现的 [] 运算符中的设计缺陷