C ++返回临时对象的混乱

时间:2012-10-18 10:15:35

标签: c++ temporary-objects

我有一个相当基本的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-object将超出范围,但这不会使构造的字符串失效吗?

如果我将返回类型更改为const char *并返回ss.str().c_str()会发生什么?

上面的代码似乎有效,但我怀疑这只是因为当我使用它时,包含'临时'对象的内存还没有被别的东西覆盖?

我不得不承认,在这种情况下我总是很困惑,如果有人可以向我解释整个“临时对象”(或者只是指向正确的方向),我会很感激。< / p> 事先提前

3 个答案:

答案 0 :(得分:13)

您正在返回一个临时对象,但由于您按值返回该对象,因此会创建该副本。如果返回临时对象的指针或引用,那将是一个错误。

如果将返回类型更改为const char *并返回ss.str().c_str(),则会返回指向std::string返回的临时ss.str()缓冲区的指针,这样会很糟糕。< / p>

答案 1 :(得分:3)

如您所见Stringstream::str()返回std::string个对象。如果没有引用,则返回std::string,这表示没有RVO(NRVO)优化复制构造函数将调用并创建有效的std::string对象。优化std::string将在没有复制构造函数的情况下移动。但是如果返回std::string&它会崩溃,因为这个对象将在函数返回后被销毁。与const char *相同的效果是因为在销毁此指针后会指向坏内存,这是危险的情况。

答案 2 :(得分:1)

假设:T val = some_function(),当您使用指定的复制构造函数或内置运算符将some_function C ++复制返回值的值返回到val时。因此,如果你返回一个intstd::string根本就没有问题,但是如果你返回一个指向一个将在函数结束时释放的内存的指针,那么!你的指针将指向无效的内存。例如,考虑一下:

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

您正在返回指向函数返回后将被释放的数据的指针(因为res将被销毁并且它将释放其内部数据)因此您将获得该地址,但该地址未指向你可能期待什么!