繁体   English   中英

C ++:何时在参数中构造的对象被破坏?

[英]C++: when object constructed in argument is destructed?

当在参数中构造的对象被破坏时,在函数调用之前还是之后?

例如,以下代码安全吗?

void f(const char*)
{ ... }

std::string g()
{ ... }
...
f(g().c_str());

它始终对我有用,但我不知道它只是未定义的行为还是实际上应该起作用。

它始终对我有用,但我不知道它只是未定义的行为还是实际上应该起作用。

不,没有未定义的行为,因为由g()生成的临时对象将在评估完整表达式(即f()函数的主体)后删除。

C ++标准n3337§12.3 / 3

当实现引入具有非平凡构造函数的类的临时对象(12.1、12.8)时,应确保为该临时对象调用构造函数。 同样,析构函数应被调用为具有非平凡析构函数的临时变量(12.4)。 临时对象被销毁,是评估(按词法)包含创建它们的点的完整表达式(1.9)的最后一步。 即使该评估以引发异常结束也是如此。 破坏的价值计算和副作用

C ++标准n3337§12.3 / 4

在两种情况下,临时变量在与完整表达式末尾不同的位置被销毁。 第一个上下文是调用默认构造函数初始化数组的元素时。 如果构造函数具有一个或多个默认参数,则在构造下一个数组元素(如果有)之前,将对在默认参数中创建的每个临时变量的销毁顺序进行排序。

C ++标准n3337§12.3 / 5

第二种情况是引用绑定到临时项时。 (...)

g()是临时的。 临时变量的生命周期会在整个完整表达式的评估过程中持续(在您的情况下,将为f(g().c_str()) )因此,除非f()将指针存储在某个地方,否则您的用法是安全的。

§12.2/ 4在两种情况下,临时变量在与全表达式末尾不同的位置被销毁。 第一个上下文是表达式作为定义对象的声明程序的初始化程序出现时。 在这种情况下,保存表达式结果的临时对象将一直保留,直到对象的初始化完成为止。 [...]

§12.2/ 5第二种情况是引用绑定到临时项时。 [...]

这两种情况均不适用于您的示例。

评估包含表达式的完整表达式后,将分解为表达式评估一部分的临时对象,除非将其绑定到命名引用。 (当前标准草案中的12.2和1.9是相关章节)。

因此,在您的示例中,构造为保存g的返回值的临时对象将在f返回之后被销毁。

暂无
暂无

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

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