简体   繁体   English

C++ 返回临时对象混乱

[英]C++ returning temporary objects confusion

I have a rather basic C++ question: Consider a function that takes some input parameters and creates a std::string from those parameters like the one below:我有一个相当基本的 C++ 问题:考虑一个接受一些输入参数并从这些参数创建一个std::string的函数,如下所示:

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?我知道当函数返回时stringstream对象将超出范围,但这不会使构造的字符串也无效吗?

What would happen if I changed the return type to const char * and returned ss.str().c_str() instead?如果我将返回类型更改为const char *并改为返回ss.str().c_str()会发生什么情况?

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).如果有人能向我解释这整个“临时对象”的事情(或者只是指出正确的方向),我将不胜感激。

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.如果将返回类型更改为const char *并返回ss.str().c_str() ,您将返回指向ss.str()返回的临时std::string的某个缓冲区的指针,这将很糟糕。

As you see Stringstream::str() returns std::string object.如您所见 ,Stringstream::str()返回std::string对象。 You returns std::string without reference that means that without RVO(NRVO) optimization copy constructor will call and create valid std::string object.您返回没有引用的std::string ,这意味着没有 RVO(NRVO) 优化复制构造函数将调用并创建有效的std::string对象。 With optimization std::string will be moved without copy constructor.通过优化std::string将在没有复制构造函数的情况下移动。 But if will return std::string& it will crash because this object will be destroyed after function return.但是如果将返回std::string&它将崩溃,因为该对象将在函数返回后被销毁。 Same effect will be with const char * because after destroying this pointer will point on bad memory and this is dangerous situation. const char *也会产生同样的效果,因为销毁此指针后将指向坏内存,这是危险的情况。

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.假设: T val = some_function() ,当您从some_function返回一个值时,C++ 使用指定的复制构造函数或内置运算符将返回值的值复制到val中。 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.因此,如果您返回一个intstd::string根本没有问题,但是如果您返回一个指向将在函数结束时释放的内存的指针,哎呀。:您的指针将指向无效内存。 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!您正在返回指向将在函数返回后立即释放的数据的指针(因为res将被销毁并且它将释放其内部数据)因此您将获得地址,但该地址并不指向您可能期望的地址!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM