向量/数组边界仅在声明定义时检查
vector/array bounds check only when a define is declared
我创建了自己的容器,该容器是从向量继承的。我想以一种由 #define 决定检查边界的方式重新实现operator[]
。
所以举个例子,忽略模板参数表,因为它们既复杂又无关紧要
class MyArray : vector<double>
{
//...
virtual double& operator[](const size_type& index);
virtual const double& operator[](const size_type& index) const;
//...
}
double& MyArray::operator[](const size_type& index)
{
#ifdef DEBUG_ENABLED
return this->at(index);
#else
return (*this)[index];
#endif
}
但是,这不起作用,因为由于operator[]
是重载的,因此在 #else
处调用 operator[]
将变得递归。
我想根据我的 #define 进行边界检查,而不是基于我使用的是std::vector<>::at()
还是std::vector<>::operator[]
。
我该如何解决这个问题?
编辑:由于它提供了很多使用std::vector作为成员而不是继承,我必须提到这样做对我来说不是一个好的解决方案,因为我必须重新实现std::vector的所有成员函数。这可不是那么令人愉快的!
只需根据需要调用基类成员函数:
double& operator[](size_type index)
{
#ifdef DEBUG_ENABLED
return std::vector<double>::at(index);
#else
return std::vector<double>::operator[](index);
#endif
}
您也应该提供此内容的const
版本。另请注意,您可能不希望将此运算符设为virtual
。
首先,从标准容器派生不是一个好主意,因为它们缺乏正确支持用作基类的功能(例如虚拟析构函数)。 标准容器的目的是它们不会用作基础。
但是,如果必须执行此操作,请添加此内容;
class MyArray : vector<double>
{
// all your other stuff
typedef vector<double> Base;
};
double& MyArray::operator[](const size_type& index)
{
#ifdef DEBUG_ENABLED
return this->at(index);
#else
return (*((Base *)this))[index];
#endif
}
函数中的类型转换通常被认为最好使用static_cast
来完成,但你明白了。
最好使容器成为类的成员,并将运算符函数的各种成员转发到包含的成员。
class MyArray
{
// all your other stuff
private:
std::vector<double> data;
};
double& MyArray::operator[](const size_type& index)
{
#ifdef DEBUG_ENABLED
return data.at(index);
#else
return data[index];
#endif
}
最后,无论哪种方式,operator[]()
都不必是虚拟的。
"由于使用 std::vector作为成员而不是继承提供了很多东西,我不得不提到这样做对我来说不是一个好的解决方案,因为我必须重新实现 std::vector 的所有成员函数。这可不是那么令人愉快的!
你不必这样做。我在这里使用继承来减轻压力。
#include <iostream>
#include <vector>
using namespace std;
template <typename T>
class Vector_ : private vector<T>
{
public:
virtual ~Vector_(){}
virtual const T& operator[](const size_t index);
virtual const T& at(const size_t index);
};
/*
<<I would like to make the check for bounds based on my #define, and not based on
std::vector<>::at() or std::vector<>::operator[]. >>
*/
template <typename T>
const T& Vector_<T>::operator[](const size_t index)
{
#ifdef DEBUG_ENABLED
return (*((vector<T>*)this))->at(index)
#else
return (*((vector<T> *)this))[index];
#endif
}
template <typename T>
const T& Vector_<T>::at(const size_t index)
{
#ifdef DEBUG_ENABLED
return (*((vector<T>*)this))->at(index)
#else
return (*((vector<T>*)this))[index];
#endif
}
//test...
Vector<int>_ vec;
vec.push_back(3);
vec[2]; or vec.at(2); //no exception
#define DEBUG_ENABLED
vec[2]; or vec.at(2); //exception
相关文章:
- 如何在C++中声明/定义相互依赖的模板?
- C++概念是否允许我的类在声明/定义中指定它满足某些概念?
- MSVC:无法识别的模板声明/定义(使用 Clang/GCC 编译)
- 我可以重用同一个模板来声明/定义多个东西吗(而不复制模板代码)
- C++-模板类中模板函数的单独声明/定义
- 在C 中使用继承时,请避免使用未缴纳的函数声明/定义
- C++模板能否确定所声明/定义的实例是否为常量
- 如何在程序中声明/定义一次并在两个类中使用映射列表
- LBNF,C函数声明/定义,减少冲突
- 声明/定义返回具有自动返回类型的 valarray 的函数时的隔离错误
- #用{}和声明定义混淆
- CTOR 声明/定义中接受的 const 限定符(LLVM 错误?)
- C++ 从一个源文件中声明/定义的变量从另一个源文件访问另一个源文件
- 无法识别的模板声明/定义
- 只在.cpp中声明/定义静态方法可以吗
- 声明/定义自定义类定制对象的正确方法
- typedef声明定义未命名类时链接失败
- 用visual c++实现COM对象的声明/定义和实例化
- VS 2012中的显式模板声明/定义
- 命名空间内的友元函数声明/定义