当在参数中构造的对象被析构时
C++: when object constructed in argument is destructed?
当在参数中构造的对象在函数调用之前或之后被析构时?
。下面的代码安全吗?
void f(const char*)
{ ... }
std::string g()
{ ... }
...
f(g().c_str());
它总是对我有效,但我不知道这只是未定义的行为还是它实际上应该工作。
g()
是临时的。临时的生命周期延长整个全表达式的整个求值时间(在您的情况下,这将是f(g().c_str())
),因此您的使用是安全的,除非f()
将指针存储在某处。
§12.2/4在两种上下文中,临时变量在不同于fullexpression结尾的位置被销毁。第一个上下文是当表达式作为定义对象的声明符的初始化项出现时。在这种情况下,保存表达式结果的临时变量应该一直存在,直到对象的初始化完成。[…]
§12.2/5第二个上下文是当引用被绑定到临时对象时。[…]
这两种情况在您的示例中都不适用。
作为表达式求值的一部分构造的临时对象在对包含该表达式的完整表达式求值后被析构,除非它被绑定到一个命名引用。(现行标准草案12.2和1.9为相关章节)。
因此,在您的示例中,用于保存g
返回值的临时构造将在f
返回后被销毁。
它总是为我工作,但我不知道它只是未定义的行为或者它实际上应该工作。
不,没有未定义行为,因为g()产生的临时对象将在计算完整表达式后被删除,即f()函数的主体。
c++标准n3337 § 12.3/3
当实现引入具有非平凡构造函数(12.1)的类的临时对象时,12.8),它应确保为临时对象调用构造函数。类似地,析构函数应为用非平凡析构函数调用临时函数(12.4)。临时对象作为最后一步被销毁在计算(词法上)包含创建它们的点的完整表达式(1.9)时。这是真的即使该求值以抛出异常结束。析构
的值计算和副作用c++标准n3337 § 12.3/4
有两种上下文中,临时变量在不同于full-结束的位置被销毁表达式。第一个上下文是调用默认构造函数初始化数组元素的时候。如果构造函数有一个或多个默认参数,销毁在默认值中创建的每个临时参数参数在构造下一个数组元素(如果有)之前进行排序。
c++标准n3337 § 12.3/5第二个上下文是当引用绑定到临时对象时。(…)
- 什么时候调用组成单元对象的析构函数
- 使用基类指针创建对象时,缺少派生类析构函数
- 对具有动态分配的内存和析构函数的类对象的引用
- C++析构函数调用两次,堆栈分配的复合对象
- 如何从 Gtk::窗口调用派生对象的析构函数
- 为什么数组中对象的析构函数在被另一个对象替换时不被调用?
- 为什么为未删除的对象调用析构函数?
- 对象的构造函数和析构函数
- 循环中本地对象的析构函数是否保证在下一次迭代之前被调用?
- C++使用函数对象的线程,如何调用多个析构函数而不是构造函数?
- 从未调用shared_ptr对象的析构函数
- 是否可以在其析构函数中使用指向已销毁对象的指针?
- 使用私有析构函数删除动态分配的对象
- 为什么在这里调用析构函数,以及在调用该对象析构函数后如何调用对象成员函数?
- 对象析构函数在多线程处理时不断被调用,但该对象并未超出范围
- C++包含包含指针的对象的对象析构函数
- C++类对象析构函数控件
- Objective-C++C++对象析构函数
- 结构对象析构函数
- 在Exit()时调用基本对象析构函数