[英]C++ returning temporary objects confusion
我有一个相当基本的 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?
}
我知道当函数返回时stringstream
对象将超出范围,但这不会使构造的字符串也无效吗?
如果我将返回类型更改为const char *
并改为返回ss.str().c_str()
会发生什么情况?
上面的代码似乎可以工作,但我怀疑这只是因为包含“临时”对象的内存在我使用它时还没有被其他东西覆盖?
我不得不承认,一般来说,我在这种情况下很困惑; 如果有人能向我解释这整个“临时对象”的事情(或者只是指出正确的方向),我将不胜感激。
您正在返回一个临时对象,但是因为您按值返回它,所以创建了副本。 如果您返回临时对象的指针或引用,那将是一个错误。
如果将返回类型更改为const char *
并返回ss.str().c_str()
,您将返回指向ss.str()
返回的临时std::string
的某个缓冲区的指针,这将很糟糕。
如您所见 ,Stringstream::str()返回std::string
对象。 您返回没有引用的std::string
,这意味着没有 RVO(NRVO) 优化复制构造函数将调用并创建有效的std::string
对象。 通过优化std::string
将在没有复制构造函数的情况下移动。 但是如果将返回std::string&
它将崩溃,因为该对象将在函数返回后被销毁。 const char *
也会产生同样的效果,因为销毁此指针后将指向坏内存,这是危险的情况。
假设: T val = some_function()
,当您从some_function
返回一个值时,C++ 使用指定的复制构造函数或内置运算符将返回值的值复制到val
中。 因此,如果您返回一个int
或std::string
根本没有问题,但是如果您返回一个指向将在函数结束时释放的内存的指针,哎呀。:您的指针将指向无效内存。 例如考虑这个:
const char* some_function() {
std::string res( ... );
//...
return res.c_str();
}
您正在返回指向将在函数返回后立即释放的数据的指针(因为res
将被销毁并且它将释放其内部数据)因此您将获得地址,但该地址并不指向您可能期望的地址!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.