Это то, что я до сих пор. Выдает исключение, когда я пытаюсь получить доступ к индексу за пределами. Я пытался сказать «вернуть NULL», если диапазон выходит за пределы для перегруженного оператора индекса, но он не работает. Проблема в том, что когда я пытаюсь присвоить значение индексу, превышающему верхний предел, это позволяет этому произойти. Как с текущим кодом, если я изменяю< 8 «в основной функции до»< 9 «, он использует элемент массива 8 без проблем, но я хочу, чтобы у него были проблемы с этим. Любая помощь приветствуется.
#include <iostream>
#include <stdexcept>
using namespace std;
//L for lower-bound, U for upper-bound
template <typename T, int L, int U>
class LBArray
{
public:
LBArray()
{
lbound = L;
ubound = U;
data = new T[ubound - lbound];
}
T& operator[](int index)
{
if (index < lbound || index > ubound)
{
throw out_of_range("index out of bounds");
}
return data[index - lbound];
}
~LBArray()
{
if (data) delete[] data;
}
private:
T *data;
int lbound;
int ubound;
};
int main(int argc, char** argv)
{
LBArray<int, 5, 7> data;
cout << "LBArray<int, 5, 7> data\n";
for (int x = 5; x < 8; x++)
{
data[x] = x;
cout << endl << "data[" << x << "] = " << data[x];
}
return 0;
}
Вы создаете массив от 5 до 7, и я предполагаю, что 5 и 7 включены, тогда у вас есть 3 элемента data [5], data [6], data [7], но в вашем коде:
data = new T[ubound - lbound];
и что 2 элемента 7-5 = 2. Вы теряете один элемент.
Поэтому я думаю, что вам нужно сделать так:
data = new T[ubound - lbound + 1];
После этого изменения все работает нормально, но вы не используете try..catch, тогда ваш код выключится.
Если вы не хотите использовать try..catch, я предлагаю вам следующий код:
T& operator[](int index)
{
if (index < lbound || index > ubound)
{
T nullVar = NULL;
return (T&)nullVar;
}
return data[index - lbound];
}
При попытке получить элемент с неверным индексом функция возвращает NULL.
Вот реализация, которая использует std :: vector в качестве основного контейнера:
#include <iostream>
#include <stdexcept>
#include <vector>
template <typename T, size_t L, size_t U>
class LBArray
{
std::vector<T> data;
void checkIndex(size_t index)
{
if ( index < L || index >= U )
throw out_of_range("index out of bounds");
}
public:
LBArray() : data(U - L) {}
T& operator[](size_t index)
{
checkIndex(index);
return data[index - L];
}
T& operator[](size_t index) const
{
checkIndex(index);
return data[index - L];
}
};
using namespace std;
int main()
{
LBArray<int, 5, 7> data;
cout << "LBArray<int, 5, 7> data\n";
for (int x = 5; x < 8; x++)
{
data[x] = x;
cout << endl << "data[" << x << "] = " << data[x];
}
}
Обратите внимание, что operator[]
перегружен как для постоянного, так и для неконстантного доступа. Кроме того, класс LBArray теперь можно безопасно копировать, так как std::vector
делает управление памятью.