C ++:当参数构造的对象被破坏时?

时间:2014-06-21 23:42:26

标签: c++

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

E.g。以下代码是否安全?

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

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

它总是对我有用,但我不知道它只是未定义的行为,或者它实际上应该有效。

3 个答案:

答案 0 :(得分:2)

  

它总是对我有用,但我不知道它只是未定义的行为   或者它实际上应该工作。

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

C ++标准版n3337 § 12.3 / 3

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

C ++标准版n3337 § 12.3 / 4

有两种情况下,临时人员在不同时刻被摧毁,而不是在完全结束时 表达。第一个上下文是调用默认构造函数来初始化数组的元素。如果 构造函数有一个或多个默认参数,破坏默认情况下创建的每个临时值 在构造下一个数组元素之前,参数是按顺序排序的。

C ++标准版n3337 § 12.3 / 5

第二个上下文是引用绑定到临时的。 (...)

答案 1 :(得分:2)

g()是暂时的。在评估整个完整表达式的整个时间内(在您的情况下,这将是f(g().c_str())),temptence的生命周期会延长。因此,除非f(),否则您的使用是安全的将指针存储在某处。

  

§12.2/ 4有两种情况下,临时表在不同于完整表达结束时被摧毁。第一个上下文是表达式作为定义对象的声明符的初始值设定项。在该上下文中,保存表达式结果的临时值将持续存在,直到对象的初始化完成。 [...]

     

§12.2/ 5第二个上下文是指引用绑定到临时。 [...]

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

答案 2 :(得分:2)

在评估包含表达式的完整表达式之后,构建作为表达式求值的一部分构造的临时对象,除非它绑定到命名引用。 (目前的标准草案中的12.2和1.9是相关部分)。

因此,在您的示例中,g返回后,将保留用于保存f返回值的临时构造。