0
vector<int> a = {1,2,3};
a[1] = 54;    // I want to achieve this in my Darray implementation
int i = 0;
a[i] = 10     // This also

I am trying to implement dynamic arrays in c++. Below is my code :
//-------- means it has not been defined yet

// custom Exception class for handling bizarre situations
#include <iostream>
using namespace std;
class MyException {
public:
  MyException() {
    cout << "\nException occurred !! Program will terminate...\n";
    exit(0);
  }
  MyException(string message) {
    cout << "\nException occurred : " << message
         << ".\nProgram will terminate...\n";
    exit(0);
  }
};

//================================================================================
// class for Dynamic array
template <typename T> //
class Darray {
  T *arr;          // Dynamic array
  size_t len, cap; // length and capacity
  /*
    len : number of elements currently Darray contains
    cap : number of elements Darray can hold without resizing
  */

public:
  Darray();
  Darray(size_t);
  Darray(Darray<T> &);
  // Darray(T *); //---------------

  size_t capacity();
  size_t length();
  void resize(size_t);
  bool empty();

  T operator[](int);
  T operator[](T);
  void operator=(T); //-------------
  void operator=(Darray);

  void push(T);
  T pop();

  T back();
  T elemAt(int);
  T front();

  T *data();
  void assign(Darray);       //---------------
  void assign(T *);          //--------------
  void insertAt(T, int);     //--------------
  void erase();              //-------------
  void clear();              //---------------
  void swap(Darray, Darray); //---------
};

//================================================================================
// default constructor for 0 capacity
template <typename T> //
Darray<T>::Darray() {
  arr = new T[0];
  len = 0;
  cap = 0;
}

//================================================================================
// parameterized constructor with given cap
template <typename T> //
Darray<T>::Darray(size_t cap) {
  arr = new T[cap];
  this->cap = cap;
  len = 0; // no elements initially
}

//================================================================================
// copy constructor with given Darray
template <typename T> //
Darray<T>::Darray(Darray<T> &temp) {
  cap = temp.capacity();
  len = 0;

  arr = new T[cap];
  while (len < temp.length()) {
    arr[len] = temp[len];
    len++;
  }
}

//================================================================================
// operator[] for getting elements
template <typename T> //
T Darray<T>::operator[](int index) {
  if (empty())
    throw MyException("Darray is empty");
  if (index < 0 || index > len - 1)
    throw MyException("Invalid index. Index should be in range 0 to length-1");
  return arr[index];
}

//================================================================================
// to check if Darray is empty
template <typename T> //
bool Darray<T>::empty() {
  return len < 1;
}

//================================================================================
// push elements at the end
template <typename T> //
void Darray<T>::push(T element) {
  if (len == cap)
    resize(cap + (cap / 2) + 1); // resizing the array
  // +1 to ensure arrays of size 0 or 1 are also resized ;-)

  arr[len] = element;
  len++;
}

//================================================================================
// remove and gives the last element of Darray
template <typename T> //
T Darray<T>::pop() {
  if (empty())
    throw MyException("Darray is empty");
  return arr[--len];
}

//================================================================================
// gives the last element of Darray
template <typename T> //
T Darray<T>::back() {
  if (empty())
    throw MyException("Darray is empty");
  return arr[len - 1];
}

//================================================================================
// gives the first element of Darray
template <typename T> //
T Darray<T>::front() {
  if (empty())
    throw MyException("Darray is empty");
  return arr[0];
}

//================================================================================
// gives element at pos
template <typename T> //
T Darray<T>::elemAt(int index) {
  if (empty())
    throw MyException("Darray is empty");
  if (index < 0 || index > len - 1)
    throw MyException("Invalid index. Index should be in range 0 to length-1");

  return arr[index];
}

//================================================================================
// length gives number of elements currently present in the array
template <typename T> //
size_t Darray<T>::length() {
  return len;
}

//================================================================================
// capacity gives total capacity of the array
template <typename T> //
size_t Darray<T>::capacity() {
  return cap;
}

//================================================================================
// returns a pointer to first element of Darray
template <typename T> //
T *Darray<T>::data() {
  if (empty())
    return NULL;
  return arr;
}

//================================================================================
// resize the array to given size
template <typename T> //
void Darray<T>::resize(size_t newSize) {

  if (newSize < 0)
    throw MyException("Size cannot be negative");

  if (newSize == cap) // no need to resize
    return;

  T *temp;  // temp array to hold the elements temporarily
  size_t t; // t holds the number of elements to be copied in the resized Darray

  if (newSize < len) {
    t = newSize;
    temp = new T[newSize];

    // copying to temp,new size is less, some elements will be lost
    for (int i = 0; i < t; i++) {
      temp[i] = arr[i];
    }
  } else {
    t = len;
    temp = new T[len];

    // copying all the elements from original array to temp
    for (int i = 0; i < t; i++) {
      temp[i] = arr[i];
    }
  }

  arr = new T[newSize]; // resizing the Darray

  // copying elements from temp to original Darray
  for (int i = 0; i < t; i++) {
    arr[i] = temp[i];
  }
  cap = newSize;
  len = t;
}

int main()
{
  Darray<char> a(0);
  a.push('A');
  a.push('B');
  a.push('C');
  a.push('D');
  a.push('E');
  // a.push('F');
  // a.push('G');
  // a.push('H');

  for (int i = 0; i < a.length(); i++) {
    cout << a[i] << " ";
  }

  cout << a.length() << " " << a.capacity() << endl;

  return 0;
}

Is overloading the assignment operator to assign elements at given index of my dynamic array possible?

Something like:

Darray<int> a(5);
a[1] = 26;

Also if I overload the constructor to take array as T* and create a Darray(0) it becomes ambiguous (null pointer and Darray of size 0). How to overcome this?

2
  • 1
    The T operator[](T); overload doesn't make any sense. Lets say that T is a class Something, why would you use that for an index? Commented Aug 24, 2022 at 10:34
  • Yes that is a mistake.I wast trying to achieve something like assigning element T to some index i but = is a binary operator. So I left is as it is on purpose Commented Aug 24, 2022 at 10:51

1 Answer 1

2

Your subscript operator returns by value. That means it returns a brand new copy.

Assigning to this copy will not change the original inside your "array".

You should return by reference instead:

T& operator[](int);

And you should probably add a "constant" overload as well:

T const& operator[](int) const;
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, it works. It means returning by reference will help if fetching the value at that index like cout<<a[i] ; and also assigning a value like a[i] = 10; It is a bit tricky for me, can you please explain both the situations. Like the first one is giving the value at that index and second is giving the address for assignment. But the operator function is same.
Also please see another question at the last.
@vallabhtiwari If you had (for example) int a; int& ref_a = a; ref_a = 10; would it surprise you that the value of a is changed to 10? It's the same when you return a reference from your function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.