0

I'm having difficulties overloading the (+) operator for a simple class (Seq) that stores a list of numbers and the list dimension. For some reason only the first element of the list becomes zero after the customized addition, while the other elements are as expected. Before returning the addition result I print the data to show that internally the result is consistent, then the problem somehow occurs during the assignment after the addition takes place. The following code reproduces this behavior.

#include <cmath>
#include <iostream>

class Seq
{
  private:
    size_t  dim;
    double* x;
  public:
    Seq();                                // create empty sequence
    Seq(size_t dim);                      // create sequence of size dim
    Seq(size_t dim, const double* x);     // create sequence
    Seq(Seq* s);                          // copy existing sequence
    ~Seq();                               // free memory
    void   setEntry(size_t i, double xi); // set single element
    double getEntry(size_t i);            // get single element
    void   showSeq();                     // print sequence
    Seq    operator+(Seq& s);             // define sequence addition
};

Seq::Seq()
{
    dim = 0;
    x = NULL;
}

// cunstructor that only allocates memory
Seq::Seq(size_t dim0)
{
    dim = dim0;
    x = new double[dim];
}

// constructor that copies data
Seq::Seq(size_t dim0, const double* x0)
{
    dim = dim0;
    x = new double[dim];
    for (size_t i = 0; i < dim; i++) {
        x[i] = x0[i];
    }
}

Seq::Seq(Seq* s)
{
    dim = s->dim;
    x = new double[dim];
    for (size_t i = 0; i < dim; i++) {
        x[i] = s->getEntry(i);
    }
}

Seq::~Seq()
{
    delete[] x;
}

void
Seq::setEntry(size_t i, double xi)
{
    if (i < dim) {
        x[i] = xi;
    } else {
        std::cout << "setEntry: index out of range" << std::endl;
    }
}

double
Seq::getEntry(size_t i)
{
    if (i < dim) {
        return x[i];
    } else {
        std::cout << "getEntry: index out of range" << std::endl;
    }
}

// print data
void
Seq::showSeq()
{
    for (size_t i = 0; i < dim; i++) {
        std::cout << x[i] << "  ";
    }
    std::cout << std::endl;
}

Seq
Seq::operator+(Seq& s)
{
    // check compatibility
    if (this->dim == s.dim) {
        Seq rslt(this);
        for (size_t i = 0; i < s.dim; i++) {
            rslt.setEntry(i, this->getEntry(i) + s.getEntry(i));
        }
        std::cout << "before leaving (+) ";
        rslt.showSeq();
        return rslt;
    } else {
        std::cout << "operator(+): incompatible dimensions"
                  << std::endl;
        Seq rslt; // default empty sequence
        return rslt;
    }
}

int
main()
{
    double data1[] = { 2, 3, 1 };
    double data2[] = { 1, 3, 2 };

    Seq x(3, data1);
    std::cout << "x = ";
    x.showSeq();

    Seq y(3, data2);
    std::cout << "y = ";
    y.showSeq();

    Seq z = x + y;
    std::cout << "z = ";
    z.showSeq();

    return 0;
}

Thanks for your help.

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
  • Why is `Seq operator+(Seq& s);` not `Seq& operator+(const Seq& s);`? – Jesper Juhl Aug 02 '20 at 15:50
  • 2
    [Rule of three](https://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming)). If your class needs a user-defined destructor, it also needs a user-defined copy constructor and copy assignment operator. Note that `Seq(Seq*)` is **not** a copy constructor. What happens in practice is that you end up with multiple instances of `Seq` all holding the same `double*` pointer and all thinking they own it. When the first of those is destroyed, it deallocates the array. When the others attempt to access that array later, the program exhibits undefined behavior. – Igor Tandetnik Aug 02 '20 at 15:52
  • Start with the member function `Seq& operator+=(const Seq& rhs);` then implement the free function `Seq operator+(const Seq& lhs, const Seq& rhs);` using the member function. – Ted Lyngmo Aug 02 '20 at 15:56
  • @JesperJuhl, I realized that I was trying to implement a free function inside the class. – David Ciro Aug 03 '20 at 01:40
  • Thanks @IgorTandetnik, that was most of the problem. I will update the code to show the new implementation. – David Ciro Aug 03 '20 at 01:44
  • 1
    Thanks @TedLyngmo, that worked out. I didn't realize that operators could be defined as free functions. I'll update with the solution. – David Ciro Aug 03 '20 at 01:47

0 Answers0