Reference or not a Reference that is the question...

I am working on a programming assignment for data structures and seems to be going just fine except for a single warning that I cannot make much sense about.

Everything centers around the code:
1
2
3
4
5
6
7
8
        // assignment operator
        Polynomial& Polynomial::operator=(const Polynomial& other){
			Polynomial temp;
			for(PolyNode* current_ptr=firstTerm; current_ptr==nullptr; current_ptr=current_ptr->next){
				temp.set_coefficient(current_ptr->coefficient, current_ptr->degree);
			}
			return temp;
		}


This method takes a reference overrides the = operator and takes a constant Polynomial reference and should return a Polynomial reference. The method declaration was given by my instructor in a the header file to implement so that it correct assignments will pass his automated tests.

Problem is that this generates a warning:

polynomial.cpp: In member function 'Polynomial& Polynomial::operator=(const Polynomial&)':
polynomial.cpp:115:15: warning: reference to local variable 'temp' returned [enabled by default]


Of course I can eliminate the reference on the return type declaration and the warning disappears... It seems like a good solution because the other operator overloading methods do not return a reference type. Problem is I do not understand why it would be returning a reference or not and if it might cause a problem or if maybe there is something else wrong with my method that I am over looking.

Can anyone shed some light on 1: why the operator= overloading would return a referenced type where the others do not. 2: Would there be any foreseeable issue with eliminating the reference on the return type that might cause problems with the way the method behaves?

Thanks in advance for any thoughts.
You want to return a reference for one key reason: Not making a copy of the returned data. Returning a reference means you are only returning something that points to the return data itself. You are getting the warning because you are returning a reference to a local variable. Local variables are created on the stack and are destroyed once out of scope.

Take a look here for more information about assignment operators:
http://www.cplusplus.com/articles/y8hv0pDG/

Hint: See how the assignment operator works in the article. How does it assign values of the source to the target object?
@vince1027

I am not 100% I understand it completely even after reading the article several times but considering what you wrote and some more reading I think this is what the situation is...

The problem is in the scope essentially. I took a method called by another polynomial class object that is designed to assign a polynomial to the calling polynomial. (Hope that makes sense)

The issue is that what I did in my method was not modify the this which was calling the assignment operator. All that I did was create a temporary object on the stack inside the method, copied the bits from the right hand side that was passed with the operator=, and then returned the temporary object. The problem is that when the method completes it clears out the stack and my temporary polynomial with it and so the returned object is not really on the stack anymore.

What I think I need to be doing is (please correct me if I'm wrong) making sure the "this" that called the operator= method has nothing assigned to it (delete anything that is assigned to it if it exists) and then overwrite the the contents of the passed polynomial constant referenced "other" to the "this" and return the "this" back at the end of the method.

Does this seem correct at all or am I still not quite understanding something...?

Thanks again for your help.

> copied the bits from the right hand side that was passed with the operator=
No, you never touched `other' in your code.

> (delete anything that is assigned to it if it exists)
¿what do you mean with `delete' ?
After you do A=B you expect that A and B hold the same state.
¿how do you define the state?
Last edited on
@ne555

> copied the bits from the right hand side that was passed with the operator=
No, you never touched `other' in your code.


Sorry it was late and I am still a noob in training.... but your are right I did not connect the pointer to other at all... Never noticed though so I thanks for pointing it out so that I can correct the glaring mistake in my new code.

[quote> (delete anything that is assigned to it if it exists)
¿what do you mean with `delete' ?][/quote]

What I meant with delete is say A and B are vectors of ints instead of my polynomial lists.
If:
A={9,8,7,6,5,4}
B={0,1,2,3}

And I copy B's contents over to A without deleting A I would end up with:

A={0,1,2,3,5,4} or at the very least A={0,1,2,3, , }

which means A!=B because of extra values or different capacity vectors depending on the copy implementation.

So first I need to destruct A if it declared and initialized to clear out anything stored in A so that A={}.

Then copy B's contents over to A so that A==B.

But this is a semantic exercise without some code to show so is this version better?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
        // assignment operator
        Polynomial& Polynomial::operator=(const Polynomial& other){
			if(this==&other){
				return *this;
			}
			PolyNode* temp;
			for(PolyNode* current_ptr=firstTerm; current_ptr!=nullptr; current_ptr=temp){
				temp=current_ptr->next;
				delete current_ptr
			}
			firstTerm=nullptr; //not sure if this would be correct but I need "this" to be the head of the copied list where firstTerm==nullptr so set_coefficent works
			for(PolyNode* current_ptr=other.firstTerm; current_ptr!=nullptr; current_ptr=current_ptr.next){
				this->set_coefficient(current_ptr->coefficient, current_ptr->degree);
			return *this;
		}


Thanks again for the insights.
Note that your operator= contains the equivalent of the destructor followed by the equivalent of the copy constuctor.

If you write a swap function (which, if I understand your use case, is trivial:

1
2
3
void Polynomial::swap(Polynomial& other) {
    std::swap(firstTerm, other.firstTerm);
}


then your assignment operator becomes simply:

1
2
3
4
5
Polynomial& Polynomial::operator=(Polynomial other)
{
    swap(other);
    return *this;
}


(you've written the copy constructor and the destructor, I hope? If not, you will have to write them anyway)
Last edited on
@Cubbi

I was unfamilar with the swap function in std so I looked it up and it leaves me with a single question.

Will it work since the Polynomial reference other was passed as constant?

When I looked up swap it appears to actually change the value of both of the called and the passed which should violate "const Polynomial& other" that was passed... right?

Sorry if I am completely missunderstanding something...

It's not const Polynomial& other in the copy-and-swap operator=, it's just Polynomial other.
Topic archived. No new replies allowed.