tags:

views:

290

answers:

4

Hello,

I need to implement the unary minus for a class. As the class is quite complicated, I must call the constructor in some way. If I try -

ClassName ClassName::forUnaryMinus(){
    ClassName retval(_parameters);
    //do stuff
    return retval;
}

The compiler complains - warning C4172: returning address of local variable or temporary

If I try:

ClassName * ClassName ::forUnaryMinus(){
    ClassName *retval = new ClassName (_parameters);
    //do stuff
    return retval;
}

I have a memory leak. So what is the proper way to do this?

A: 

Edit: wrong answer ! (I need to go back to school ;-) )

As Bill pointed out local variables are returned by value... I was merely trusting the compiler's alleged error message, and dove right in! Apologies to the group.

Now... in that light, the OP's question doesn't seem to make sense (unless it's something to do with ClassName or some other type I need to learn about), so I'd better shut-up and make way for those who know...

In fairness, my heavy C/C++ coding days are behind me and I never used nor needed return by value for types other than ints, longs and such...



Your logic seem to require the creation of a new ClassName object. This will therefore need to be disposed of, when you are done needing it.

Your first attempt is, thankfully, caught as incorrect by the compiler because the new object is stored in a location that will become invalid when the function returns (local variables are put on the stack and this makes it for a convenient place to have "stuff", without worrying about disposing of it, but of course this storage is only valid for the function where the variable is declared an any function that is called from it.)

mjv
Since the function returns by copy, the fact that the object is on the stack doesn't matter here. The copy will be made before the object is inaccesible.
Bill
Thanks for pointing that out, Bill. You taught me something today.
mjv
+3  A: 

The first one should return a copy of the retval object you created. Are you sure that you're not returning a reference to it instead, which would explain the compiler warning? If you do, return the value instead.

Timo Geusch
+1  A: 
ClassName ClassName::forUnaryMinus(){
    ClassName retval(_parameters);
    [do stuff]
    return retval;
}

The compiler complains - warning C4172: returning address of local variable or temporary

No, it won't. It would only do that if you declared the return type as ClassName&, not ClassName. The way it is written above, it should work fine, because retval would be returned-by-copy.

sepp2k
A: 

I don't think your first snippet is an accurate representation of your code. It's perfectly legitimate to return an object on the stack, so your first snippet should be OK (retval is on the stack in forUnaryMinus, and you should be able to return it). I suspect that your actual code looks more like this:

ClassName &ClassName::forUnaryMinus(){
    ClassName retval(_parameters);
    [do stuff]
    return retval;
    }

where you are returning a REFERENCE to an object. If you are returning a reference, it's usually to the object being acted upon (so that it can be acted upon further). So it would be more like this:

ClassName &ClassName::forUnaryMinus(){
    [do stuff]
    return *this;
    }

A better code snippet would help.

Michael Kohne