简体   繁体   中英

Operator overloading with pointers

Hi there c++ programmers. I am encountering issue that i cant understand.I have strip the following program for readability reasons and left what i am having trouble with. I am trying to overload a + and = operators, but with dynamically created arrays. By themselves the + and = operator methods are producing the right results. However when i try to assign the result from the + operator to *poly3 i get "*poly3 need to be initialized" from the compiler. If i do initialize it nothing gets assign to it( i mean the result from +). My question, what is the right way to do this. I need the result poly3 to be dynamic array or a pointer as well so i can use it latter.

Thanks a lot for the help in advance.

class Polynomial
{
    private:
        int *poly;
        int size;
    public:
        Polynomial();
        Polynomial(int);
        Polynomial(string,int);
        ~Polynomial();
        void setPoly(string);
        int *getPoly() const;
        Polynomial operator+(Polynomial&);
        void operator=(const Polynomial&);
};

Polynomial::Polynomial(string polyInput, int s) 
{
    size = s+1;

     poly = new int[size];
    //set all coef position to 0
    for(int i = 0; i < size; i++){
        *(poly + i) = 0;
    }
    setPoly(polyInput);
}

Polynomial Polynomial::operator+(Polynomial &polyRight)
{
    Polynomial *result = new Polynomial(size);

    for(int i = 0; i < size; i++)
        result->poly[i] = poly[i] + polyRight.poly[i];
    return *result;
}

void Polynomial::operator=(const Polynomial &polyRight)
{
    size = polyRight.size;
    for(int i = 0; i < size; i++){
        *(poly + i) = polyRight.poly[i];
    }
}

int main()
{
    int highestExp = 4;
    Polynomial *poly1;
    Polynomial *poly2;
    Polynomial *poly3;// = new Polynomial(highestExp); // for the result
    string input1,input2;



    ifstream inputFile("data.txt");

    getline(inputFile, input1);
    getline(inputFile, input2);

    poly1 = new Polynomial(input1,highestExp);
    poly2 = new Polynomial(input2,highestExp);

    *poly3 = *poly1 + *poly2;

    system("pause");
    return 0;
}

The assignment operator must return a reference to the instance assigned to:

Polynomial& operator=(const Polynomial&);

In the implementation, you should return *this; . You must also make sure that the implementation is robust against assignment of polynomials of different size. That doesn't seem to be the case currently.

Then, in main , poly3 is uninitialized. Just drop the pointers and instantiate all the poly s as automatic storage, local variables in main() :

Polynomial poly1(input1,highestExp);
Polynomial poly2(input2,highestExp);
Polynimial poly3 = poly1 + poly2;

As an aside, your operator+ has a memory leak. You should not be using new int it. Create a local Polynomial and return it.

Furthermore, you have no destructor taking care of releasing resources, so every instantiation of a Polynomial results in a memory leak. Your class has too many responsibilities: managing resources and being a polynomial. You should let a different class take care of the memory management. Use std::vector<int> , or, if this is an exercise, write your own dynamic array-like class, and use that inside Polynomial .

To start with:

                                             // allow adding const
const Polynomial Polynomial::operator+(const Polynomial &polyRight) const
{
    Polynomial result(size); // don't use a pointer

    for(int i = 0; i < size; i++)
        result.poly[i] = poly[i] + polyRight.poly[i];
    return result;
}

make the return const to avoid the silliness of (A+B)=C;

Polynomial&  Polynomial::operator=(const Polynomial &polyRight) // return a reference
{
    size = polyRight.size;
    for(int i = 0; i < size; i++){
        *(poly + i) = polyRight.poly[i];
    }
    return *this; // allow chaining
}

Note that once you patch this up that you need to guard against A=A in operator =() :

if (this == &rhs)
{
     // do stuff
}
return *this;

Pointers point to a memory location explicitly assigned to it.

Ptr* pt = new Ptr();//pt points to a valid address in memory

Ptr* pt;//pt has not yet been initialized 

ie it is not pointing to any valid address. Using pt can cause unexpected behavior. By default pointers should point to NULL and they should be checked for !NULL and then used.

In above code Polynomial *poly3; is not pointing to any location and when we do *pol3 we are actually dereferencing a location which had never been created.

When you do Polynomial *poly3 = new Polynomial(highestExp);, you are pointing poly3 to some valid location and hence *pol3 = *poly1 + *pol2 makes sense. But beware when you do a new for poly3 you are creating one more heap storage, so you have to make sure that you free all memory assigned on heap.

A better solution would be have your opertor + return a valid pointer and have it mapped to poly3 like this:

Polynomial* Polynomial::operator+(Polynomial &polyRight)
{
  Polynomial *result = new Polynomial(size);

  for(int i = 0; i < size; i++)
    result->poly[i] = poly[i] + polyRight.poly[i];
  return result;
}

//and in main

poly3 = (*poly1 + *poly2);

Here is quite a cleanup, with some slightly different functionality and better memory management. Since I didn't know the format of your input file, I've skipped the reading from file part, and just use a new constructor of the form Polynomial(countOfExponents, x0, x1, x2, x3, ... , xn)

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <fstream>
#include <iostream>
#include <sstream>
#include <cstdarg>

using namespace std;


class Polynomial
{
    private:
        int *poly;
        int size;
    public:
        Polynomial() : size(0), poly(NULL) {}
        Polynomial(int size, ... );
        ~Polynomial() { delete[](poly); }

        void allocate(int size) { 
            if (NULL!=poly) {
                delete[](poly);
            }
            Polynomial::size = size; 
            poly=new int[size]; 
        }
        Polynomial operator+(const Polynomial&) const;
        Polynomial &operator=(const Polynomial&);
        int exponent(int p) const {
            return (p<size) ? poly[p] : 0;
        }
        string str() const;
};

Polynomial::Polynomial(int size, ...) : size(size) {
    va_list varargs;
    va_start(varargs, size);
    poly = new int[size];
    for (int i=0; i<size; i++) {
        poly[i] = va_arg(varargs, int);
    }
    va_end(varargs);
}

Polynomial Polynomial::operator+(const Polynomial &polyRight) const
{
    int newSize = max(size, polyRight.size);
    Polynomial result;
    result.allocate(newSize);

    for(int i = 0; i < newSize; i++)
        result.poly[i] = exponent(i) + polyRight.exponent(i);
    return result;
}

Polynomial &Polynomial::operator=(const Polynomial &polyRight)
{
    allocate(polyRight.size);
    memcpy(poly, polyRight.poly, sizeof(int) * size);
    return *this;
}

string Polynomial::str() const {
    stringstream out;
    for (int i=size-1; i>=0; i--) {
        out << poly[i];
        if (0<i) {
            out << "  ";
        }
    }
    return out.str();
}

int main()
{
    Polynomial one(3, 1, 2, 3);
    Polynomial two(3, 2, 3, 4);
    cout << one.str() << endl;
    cout << two.str() << endl;
    Polynomial three = one + two;
    cout << three.str() << endl;
    return 0;
}

Note that I'm also being careful not to address memory that might not exist when working with polynomials of different sizes. Accessing poly[n] on a polynomial with fewer than n exponents would cause trouble. Instead, use the exponent(n) function, which will return 0 for all exponents higher than those inside the polynomial.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM