C++ returning temporary objects confusion

2019-04-07 10:35发布

问题:

I've got a rather basic C++ question, consider a function that takes some input parameters and creates a std::string that from those parameters like the one below:

std::string constructString( int some_parameter ) {

    std::stringstream ss;

    // Construct a string (arbitrarily complex)
    ss << "Some parameter is " << some_parameter << " right now";

    return ss.str();    //Am I not returning a temporary object here?
}

I understand that the stringstream-object will go out of scope when the function returns, but doesn't that invalidate the constructed string as well?

What would happen if I changed the return type to const char * and returned ss.str().c_str() instead?

Code like the above seems to work, but I suspect that's just because the memory containing the 'temporary' object has not yet been overwritten with something else when I use it?

I have to admit, I'm rather confused in such situations in general, I'd appreciate it if someone could explain this whole "temporary objects"-thing to me (or just point me in the right direction).

thx in advance

回答1:

You are returning a temporary object, but because you return it by value, the copy is created. If you return pointer or reference to temporary object, that would be a mistake.

If you change the return type to const char * and return ss.str().c_str() you would return pointer to some buffer of temporary std::string returned by ss.str() and that would be bad.



回答2:

As you see Stringstream::str() returns std::string object. You returns std::string without reference that means that without RVO(NRVO) optimization copy constructor will call and create valid std::string object. With optimization std::string will be moved without copy constructor. But if will return std::string& it will crash because this object will be destroyed after function return. Same effect will be with const char * because after destroying this pointer will point on bad memory and this is dangerous situation.



回答3:

Assume this: T val = some_function(), when you return a value from some_function C++ copy value of returned value into val using specified copy constructor or built-in operator. So if you return an int or std::string there is no problem at all, but if you return a pointer to a memory that will be freed at end of the function, oops!! your pointer will be pointed to an invalid memory. For example consider this:

const char* some_function() {
    std::string res( ... );
    //...
    return res.c_str();
}

You are returning pointer to data that will be freed as soon as function return(since res will be destroyed and it will free its internal data) so you will get the address, but that address does not point to what you possibly expect!