title: Overloading the [] operator
body: <p>I am a beginner in C++. I am learning on how to overload operators. I have created a class <strong>Complex</strong> that represents complex numbers and methods for complex arithmetic and a class <strong>ComplexArray</strong> that represents fixed-length arrays of elements in complex vector space C.</p>
  
  <p>I get compiler errors, that it is unable to find the correct form of operator[]. However, I searched the internet and I am unable to rectify the error. Any hints/tips in the right direction would be of tremendous help.</p>
  
  <blockquote>
    <p>Severity   Code    Description Project File    Line    Suppression State<br>
    Error  C2676   binary '[': 'const ComplexArray' does not define this operator or a conversion to a type acceptable to the predefined operator  ComplexArrays   c:\users\quasa\source\repos\complexarrays\complexarrays\testcomplexarray.cpp    7   </p>
  </blockquote>
  
  <p>Here is my code:</p>
  
  <p><strong>TestComplexArray.cpp</strong></p>
  
  <pre><code>#include &lt;iostream&gt;
  #include "ComplexArray.h"
  
  Complex ComplexSum(const ComplexArray&amp; cArray, int size)
  {
      Complex sum = cArray[0];
      for (int i = 1; i &lt; size; i++)
      {
          sum = sum + cArray[i];
      }
      return sum;
  }
  
  Complex ComplexProduct(const ComplexArray&amp; cArray, int size)
  {
      Complex product = cArray[0];
      for (int j = 1; j &lt; size; j++)
      {
          product = product * cArray[j];
      }
      return product;
  }
  
  int main()
  {
      char ch;
  
      const int size = 5;
      ComplexArray cArray(size);
  
      for (int i = 0; i &lt; size; i++)
      {
          cArray[i] = Complex((double)(i + 1), 0);
          std::cout &lt;&lt; cArray[i];
      }
  
      Complex sum = ComplexSum(cArray, size);
      Complex product = ComplexProduct(cArray, size);
  
      std::cout &lt;&lt; "Sum = " &lt;&lt; sum &lt;&lt; std::endl;
      std::cout &lt;&lt; "Product = " &lt;&lt; product &lt;&lt; std::endl;
  
      std::cin &gt;&gt; ch;
      return 0;
  }
  </code></pre>
  
  <p><strong>ComplexArray.h</strong></p>
  
  <pre><code>class ComplexArray
  {
  private:
      Complex* complexArr;
      int size;
  
      ComplexArray();
  public:
      //Constructors and destructors
      ComplexArray(int size);
      ComplexArray(const ComplexArray&amp; source);
      virtual ~ComplexArray();
  
      //Range for the complexArr
      int MaxIndex() const;
  
      //Overload the indexing operator
      const Complex&amp; operator [](int index) const;
      Complex&amp; operator [](int index);
  };
  </code></pre>
  
  <p><strong>ComplexArray.cpp</strong></p>
  
  <pre><code>#include "Complex.h"
  #include "ComplexArray.h"
  
  ComplexArray::ComplexArray(int s)
  {
      size = s;
      complexArr = new Complex[size];
  }
  
  ComplexArray::ComplexArray(const ComplexArray&amp; source)
  {
      //Deep copy source
      size = source.size;
  
      complexArr = new Complex[size];
  
      for (int i = 0; i &lt; size; i++)
      {
          complexArr[i] = source.complexArr[i];
      }
  }
  
  ComplexArray::~ComplexArray()
  {
      delete[] complexArr;
  }
  
  int ComplexArray::MaxIndex() const
  {
      return (size - 1);
  }
  
  /*
  c1.operator[](int index) should return a reference to the Complex
  object, because there are two possible cases.
  
  Case 1:
  Complex c = complexArray[3];
  
  Case 2:
  complexArray[3] = c;
  
  In the second case, complexArray[3] is an lvalue, so it must return
  a Complex object  by reference, so that it can be assigned to.
  */
  
  const Complex&amp; ComplexArray::operator[] (int index) const
  {
      return complexArr[index];
  }
  
  Complex&amp; ComplexArray::operator[](int index)
  {
      return complexArr[index];
  }
  </code></pre>
  
  <p><strong>Complex.h</strong></p>
  
  <pre><code>#include &lt;iostream&gt;
  
  class Complex
  {
  private:
      double x;
      double y;
      void init(double xs, double ys); //Private helper function
  
  public:
      //Constructors and destructors
      Complex();
      Complex(const Complex&amp; z);
      Complex(double xs, double ys);
      virtual ~Complex();
  
      //Selectors
      double X() const;
      double Y() const;
  
      //Modifiers
      void X(double xs);
      void Y(double ys);
  
      //Overload binary +, = and * operators
      Complex operator + (const Complex&amp; z);
      Complex&amp; operator = (const Complex&amp; z);
      Complex operator * (const Complex&amp; z) const;
  
      //Overload unary - operator
      Complex operator -() const;
  
      friend Complex operator * (const double alpha, const Complex&amp; z);
      friend Complex operator * (const Complex&amp; z, const double beta);
  
      //Overload &lt;&lt; operator
      friend std::ostream&amp; operator &lt;&lt; (std::ostream&amp; os, const Complex&amp; z);
  
      //A complex function f(z)=z^2
      Complex square();
  };
  </code></pre>