运维开发网

C语言 可以通过引用返回临时对象

运维开发网 https://www.qedev.com 2020-03-27 10:41 出处:网络 作者:运维开发网整理
是否可以从此示例代码中的函数返回引用: string &erase_whitespace(string &text) { text.erase(**etc.**); return text; } 呼叫: string text = erase_whitespace(string("this is a test")); cout << test; 这段代码有用吗?在Visual C上
是否可以从此示例代码中的函数返回引用:

string &erase_whitespace(string &text)
{
    text.erase(**etc.**);
    return text;
}

呼叫:

string text = erase_whitespace(string("this is a test"));
cout << test;

这段代码有用吗?在Visual C上它不会崩溃但看起来不对.

谢谢

来自C 2003标准(草案)的第12.2.3节

Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created.

§12.2.4:

There are two contexts in which temporaries are destroyed at a different point than the end of the full-

expression. …

§12.2.5:

The second context is when a reference is bound to a temporary. The temporary to which the reference is

bound or the temporary that is the complete object to a subobject of which the temporary is bound persists

for the lifetime of the reference except as specified below. … A temporary bound to a reference

parameter in a function call (5.2.2) persists until the completion of the full expression containing the call.

§8.5.3.5确定何时引用必须是const类型.如果临时是具有转换运算符的类的实例,则临时绑定到非const引用是可能的,该转换运算符返回适当的引用(这是一个满口).一个例子可能更容易理解:

class Foo {
    ...
    operator Bar&() const;
...
void baz(Bar &b);
...
    baz(Foo()); // valid
    baz(Bar()); // not valid

最后一行无效是因为§12.3.2.1,其中规定“转换函数永远不会用于将[an …]对象转换为[…]相同的对象类型(或引用

它可以通过Bar的祖先和虚拟转换函数使用强制转换.

赋值是一个表达式(第5.17节),因此代码中的完整表达式(第1.9.12节)就是赋值.这给出了以下序列(暂时忘记了临时字符串可能无法绑定到非const引用):

>创建临时字符串

>临时绑定到字符串& erase_whitespace的text参数

> erase_whitespace完成它的功能.

> erase_whitespace返回对临时的引用

>临时复制到字符串文本

>临时被摧毁.

所以在这种情况下,所有人都是犹太人.正如Mike Seymour指出的那样,问题是将erase_whitespace的结果分配给引用.请注意,这可能不会立即引起问题,因为存储字符串的区域可能包含与临时销毁之前相同的数据.下次在堆栈或堆上分配一些东西但是……

0

精彩评论

暂无评论...
验证码 换一张
取 消