How would I create an Array class that can have lower bounds other than zero (in C++)?

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-25 03:57:15

问题


This is what I have so far. It throws an exception when I try to access an index out of bounds. I tried to say "return NULL" if the range is out of bounds for the overloaded subscript operator, but it's not working. The problem is when I try to assign a value to an index above the upper limit it allows it to happen. Like with the current code if I change the "< 8" in the main function to "< 9", it uses array element 8 without problem, but I want it to have a problem with that. Any help is appreciated.

#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;
}


回答1:


You create array from 5 to 7, and I suppose that 5 and 7 included, then you have 3 elements data[5], data[6], data[7], but in your code:

data = new T[ubound - lbound];

and that 2 elements 7-5 = 2. You lose one element. Therefore I think you need do like that:

data = new T[ubound - lbound + 1];

After that change all work fine, but you do not use try..catch, then your code shutdown. If you do not want to use try..catch, I offer to you next code:

T& operator[](int index)
{
    if (index < lbound || index > ubound)
    {
        T nullVar = NULL;

        return (T&)nullVar;
    }
    return data[index - lbound];
}

Attempting to get element with wrong index the function return NULL.




回答2:


Here is an implementation that uses std::vector as the underlying container:

#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];
    }
}   

Note that the operator[] is overloaded for both const and non-const access. Also, the LBArray class can now be safely copied since the std::vector does the memory management.



来源:https://stackoverflow.com/questions/24772348/how-would-i-create-an-array-class-that-can-have-lower-bounds-other-than-zero-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!