I have this in my testing.cpp:
class Supp{
public:
virtual Supp* add(Supp& val) = 0;
};
class SubA : public Supp{
public:
int val;
SubA(int a){
val = a;
}
int getVal(){
return val;
}
Supp* add(Supp& value){
SubA& a = dynamic_cast<SubA&>(value);
int tempVal = a.getVal();
int sum = val + tempVal;
SubA b =SubA(sum);
return &b;
}
};
and the lines
SubA b = SubA(sum);
return &b;
gives and error because itreturns the address to a local variable which is very bad to do, so i changed it to
SubA* b =new SubA(sum);
return b;
and it works fine with no errors, But is this not basically the same thing? why is this legal to the compiler but the previous version not?
The reason it's illegal to return the address to a local variable is once the function returns, the local variable ceases to exist, thus you're returning an address which is known to be no longer valid. (The object may still live there but its destructor will have already been called, and the memory it occupied will be used for something else at some point -- perhaps with the very next subroutine call.)
The reason it's ok to return the address returned by new
is that address is not pointing to an object that lives in a temporary location (your program stack is where locals are normally placed); rather it comes from heap memory which will persist until you dispose of it. This object doesn't rely on the scope of code it was allocated in since it's not local to that scope.
In the first example, your local variable is allocated on the stack (where all local variables for the duration of their scope) and will be immediately deallocated on returning to the calling function. As such, the pointer returned will be invalid the moment you leave the function.
In the second, you are creating a new object on the heap where it will be retained until you manually deallocate the pointer somewhere else down the line.
Initially misread the question, sorry.
The second works because you're not returning by reference, but by value. If the signature was
Supp*& add(Supp& value)
then the second would be illegal as well.
Keep in mind that objects with automatic storage duration get destroyed at the closing }
. So after the functions return, the object b
is no longer accessible. Copies of it are. If you return by value, the original goes away, but you're left with the copy.