views:

120

answers:

5

Ok, So I've googled this problem and I have searched stack overflow but I can't seem to find a good answer. So, I am asking the question on here that is particular to my problem. If it is an easy answer, please be nice, I am new to the language. Here is my problem:

I am trying to write a method for a C++ class that is overloading an operator. I want to return a copy of the instance modified but not the instance itself. For ease of example, I'll use a BigInt class to demonstrate the problem that I am having.

If I had the following code:

const BigInt & operator+() const //returns a positive of the number
{
    BigInt returnValue = *this;  //this is where I THINK the problem is
    returnValue.makepositve();   //for examples sake
    return returnValue;
}

I get the error that the return value may have been created on the stack. I know that this means that I have to create the object on the heap and return the reference. But If I were to change the 3rd line to something like:

    BigInt & returnValue = *this;

I get an error telling me that the syntax is not right.

I'm not really sure what to do, any help is much appreciated!

A: 

try

BigInt * returnValue = this;
Lucas
I tried that but the error that I got was:initial value of reference to non-const must be an lvalue
John
`this` is a pointer, i.e. `BigInt*` and cannot be assigned to a reference.
Peter Alexander
A: 

My C++ is a bit rusty, but what about:

BigInt* returnValue = new BigInt(this)
...
return *returnValue;
Timores
it's telling me that no instance of the constructor matches the argument list.
John
The problem with this approach is that you will end up leaking memory. How will you delete your newly created object? Also, it would be new BigInt(*this)
Gab Royer
+6  A: 

The problem is in your function signature. You really do have to return the entire object and not just a reference.

Your function will look like this

BigInt operator+() const //returns a positive of the number
{
    BigInt returnValue = *this;
    returnValue.makepositve();   //for examples sake
    return returnValue;
}
Gab Royer
ok, so if I return the entire object, does the object need to be created on the heap?
John
No, you can create it on the stack.
Gab Royer
No, c/c++ copy the return value from the called stack frame to the prior one. Basically what that means is, when you don't have a pointer, the object is copied when returned. (Primitives like pointers also get 'copied', but you wont notice because they just point to the same object.)
Jared P
+3  A: 

You might as well make the return value of the operator BigInt. Then the copy constructor will happen automagically on the return:

const BigInt operator+() const //returns a positive of the number
{
    BigInt returnValue = *this;  //this is where I THINK the problem is
    returnValue.makepositve();   //for examples sake
    return returnValue;
}

Now it looks like a copy constructor will happen twice, once inside the operator and another when the function returns, but with Return Value Optimization, it will actually only happen once, so performance wise it's as good as it gets.

Igor Zevaka
Actually its NRVO.
Georg Fritzsche
A: 

Note that overloaded operators should have intuitive semantics. Defining unary + to mean "absolute value", as you do in the example code provided, is extremely confusing to clients. Operators on user-defined types should behave like on the built-in types. For example, +(-5) yields -5, not +5. Thus, your implementation of operator+ should look like this:

BigInt& operator+() //returns the unchanged number
{
    return *this;
}

const BigInt& operator+() const //returns the unchanged number
{
    return *this;
}

If you want to provide an absolute value function, then do so:

BigInt abs(BigInt x)
{
    x.makePositive();
    return x;
}
FredOverflow