我有这段代码,当试图在Container中到达_arr的第三个索引时,应该抛出一个异常。它也不例外,我不明白为什么。
删除构造函数会使它引发异常,这确实很奇怪。
class X {
public:
X(int x) { std::cout << x - 1; }
};
template <class T, int d=3>
class Container {
T* _arr;
public:
Container():_arr(new T[d]){ }
void setItemAtIndex(T item, int index) { _arr[index] = item; }
X getItemAtIndex(int index) { return _arr[index]; }
};
int main()
{
Container<int> container;
for (int i = 1;i < 4;i++) {
container.setItemAtIndex(i, i);
X x = container.getItemAtIndex(i);
}
return 0;
}
我希望抛出一个异常,但实际上它输出“ 012”。
答案 0 :(得分:2)
C ++遵循这种哲学(尽管有一些例外情况违背了它)“不用为不需要的东西付钱” 。在超出数组边界时引发异常将需要进行显式检查。但是,如果您已经知道您不能超过?
for(size_t i = 0; i < sizeof(someArray)/sizeof(*someArray); ++i)
someArray[i] = 0; // i CANNOT be outside array boundaries, so why check???
这可以使C ++快速运行,但是另一方面,如果需要 ,则将这些检查强加给您(就像访问器函数中一样)。正是由于这个原因,std::vector
同时提供了operator[]
(未选中)和at
(选中,超出当前大小会引发异常)。
如果您超出范围访问数组,则会调用未定义的行为。您可能会离开,因为可能会在阵列中分配一些额外的内存。如果超出数组边界足够,则可能会看到与省略构造函数时相同的“异常”(使指针未初始化为某个随机值)。实际上,这并不是C ++的例外。这是一种访问冲突(读取程序中不存在或无法访问的内存地址),很可能被操作系统检测到,并通过某种适当的方式处理了该问题(例如linux向程序发送SIG_SEGV信号)。
答案 1 :(得分:1)
在C ++中没有规则说访问数组超出范围时必须抛出异常。这只是undefined behaviour的情况。
删除构造函数会导致它引发异常,这确实很奇怪。未定义的行为是无法预测的。我猜想您的系统最好是通过未初始化的指针来捕获访问,而不是对数组进行超出范围的访问。