-1

So I'm trying to write this class. One of the things I want to be able to do is to add two together, so I'm overloading the addition operator. But here's the thing, I don't want to return a pointer, I want to return the class "by value", so that the addition operator works without messing with pointers.

My current approach doesn't work, because the class I create goes out of scope, and the only other way I can think of is to do it with pointers. Is there any other way to do this, without calling new and allocating memory that will later have to be deleted by the user of the class?

The current code:

Polynomial operator+(const Polynomial &lhs, const Polynomial &rhs)
{

    Polynomial newPoly;
    newPoly.addWithOther(lhs);
    newPoly.addWithOther(rhs);
    return newPoly;
}
Scuba Steve
  • 1,541
  • 1
  • 19
  • 47
  • 1
    That should work fine, although I would implement it in terms of `operator+=`. – chris Nov 04 '13 at 04:03
  • Why not `Polynominal newPoly(lhs); newPoly.operator+=(rhs); return newPoly;`. Also, newPoly going out of scope shouldn't be a problem since you are `return`ing it, that suggests a problem with your copy or assignment constructors. – kfsone Nov 04 '13 at 04:07
  • 1
    You should ask yourself the following questions; if you are confused, please append the definition (not necessarily implementation) of the `Polynomial` class to your question. Does the `Polynomial` class have a default constructor, so that the statement `Polynomial newPoly` is ok? This might be generated by the compiler. Does the `Polynomial` class have a copy constructor, so that your return value can be copied into the calling context? Again, this might be generated by the compiler. Another note: writing that it "doesn't work" isn't very helpful. What compiler/runtime error do you see? – NicholasM Nov 04 '13 at 04:08
  • Its not giving an error, its outputting junk because newPoly goes out of scope. There is a copy constructor and an assignment operator overload. – Scuba Steve Nov 04 '13 at 04:10
  • It is *not* outputting junk "because newPoly goes out of scope". If that was the case, you could NEVER return anything from a function. – kfsone Nov 04 '13 at 04:11
  • BTW - operator+ only takes one argument. – kfsone Nov 04 '13 at 04:11
  • kfsone, you are incorrect.. can you explain how a class with correct values is returned when a pointer is returned instead of whats posted? – Scuba Steve Nov 04 '13 at 04:19
  • @ScubaSteve I'm not incorrect, sorry. – kfsone Nov 04 '13 at 04:22
  • And I've provided you with a demonstrable, working proof. http://ideone.com/5Gc0zK – kfsone Nov 04 '13 at 04:23
  • Yeah, that doesn't work, at least when you're dealing with a data type that has members that are more than just ints. I just spent an hour checking, and yeah, no dice. The object goes out of scope, as I said. I've overloaded my assignment operator and copy constructor, and those are working, but when 'newPoly' goes out of scope its gone, so the members of the structure thats returned are all just garbage. – Scuba Steve Nov 04 '13 at 05:33
  • The object goes out of scope but only after being hoisted by return. That's why you *can* return a std::string, its also why nobody else is answering. Google "return valuen optimization" – kfsone Nov 04 '13 at 08:54
  • Ok then buddy, why don't you make room for other people to answer then. You're really obviously wrong, and your solution doesn't work. Have you considered that your test environment just isn't overriding the values stored in memory there? Like, c'mon man. It goes out of scope and the memory is reallocated by the system. Why else would my values be totally fine at the exact moment before they are returned, and then turn into garbage. Magic? http://stackoverflow.com/questions/752658/is-the-practice-of-returning-a-c-reference-variable-evil – Scuba Steve Nov 04 '13 at 09:01
  • In the interests of diligence, I just tripple checked. Single stepping through the debugger, the deconstructor gets called, because the object goes out of scope, right after the return, and right before the stack frame returns to the original call. If this isn't "Going out of scope" I don't know what is. – Scuba Steve Nov 04 '13 at 09:29
  • When you return by value, the expiring local object is copied to the lvalue or rvalue it is going to be stored in after the scope ends, and THEN your local version goes out of scope. So the problem is *not* that your object *goes* out of scope, it's either a problem with your copy constructor or assignment operator, or lack of one. http://ideone.com/UQlUfI. Do you have move operators defined? – kfsone Nov 05 '13 at 09:14

1 Answers1

-1

Well I figured it out. The copy constructor is called right after return is called. And the return register will take a copy of your object. Its here that any objects that are not returned will go out of scope. If you don't perform a deep copy of those objects, or in my case, a 'deep enough' copy, the members will be reallocated by the system.

Scuba Steve
  • 1,541
  • 1
  • 19
  • 47
  • " Also, newPoly going out of scope shouldn't be a problem since you are returning it, that suggests a problem with your copy or assignment constructors. – kfsone yesterday " and "The object goes out of scope but only after being hoisted by return. That's why you can return a std::string, its also why nobody else is answering. Google "return valuen optimization" – kfsone yesterday" – kfsone Nov 05 '13 at 09:15
  • Cool story bro. "Hoisted" is a pretty ambiguos and confusing term to use. Poor communication all the way. – Scuba Steve Nov 06 '13 at 17:33
  • The copy constructor isn't called "right after return is called", it's called *because* of return. Return isn't a function, it's a statement, and "return localObject" is legal precisely because of what it does. You can avoid miscommunicating your question in future by providing more context for your code - take a look at the second comment to your question, I'd hit the nail on the head but lacked enough context from you to turn it into a question that explained it in terms of your code. – kfsone Nov 06 '13 at 20:08