传递类按值时,调用方或被调用方是否调用析构函数? [英] When passing a class by-value, does the caller or callee call the destructor?
问题描述
假设我有以下(经过精简的)代码:
Suppose that I have the following (trimmed down) code:
class P { P(); P(const P&); ~P(); }
void foo(P x) {
...
}
void bar() {
P p{};
foo(p); // compiler uses P::(const P&) to construct the value for x
...
// compiler calls P::~P() on p
}
编译器必须创建 p
的副本才能调用 foo
,因此 caller 会在调用之前调用副本构造函数.我的问题是,谁负责破坏这个创建的对象?似乎有两个有效的选择:
The compiler must create a copy of p
in order to call foo
, so the caller invokes the copy constructor before the call. My question is, who is in charge of destroying this created object? There seem to be two valid choices:
- 被调用方(即
foo
)在其返回值之前使用其所有按值参数调用析构函数,然后调用方释放内存(通过将其弹出堆栈). - 被叫方不执行任何操作,并且调用方(即
bar
)在foo(p)
呼叫.
- The callee (i.e.
foo
) calls the destructor on all of its by-value arguments before it returns and then the caller deallocates the memory (by popping it off the stack). - The callee doesn't do anything, and the caller (i.e.
bar
) calls the destructor on all of the temporaries before the sequence point at the end of thefoo(p)
call.
推荐答案
标准在[expr.call]/4中回答了这个问题,并给出了令人惊讶的详细说明:
The standard answers this question in [expr.call]/4, with a surprising amount of elaboration:
...每个参数的初始化和销毁都在以下情况下发生:调用函数.[示例:检查构造函数,转换函数或析构函数的访问在调用函数中的调用点.如果函数参数的构造函数或析构函数抛出例外,对处理程序的搜索始于调用函数的范围;特别是如果功能被调用有一个 function-try-block (第18条),带有可以处理异常的处理程序,该处理程序不是经过考虑的.-最终示例]
... The initialization and destruction of each parameter occurs within the context of the calling function. [ Example: The access of the constructor, conversion functions or destructor is checked at the point of call in the calling function. If a constructor or destructor for a function parameter throws an exception, the search for a handler starts in the scope of the calling function; in particular, if the function called has a function-try-block (Clause 18) with a handler that could handle the exception, this handler is not considered. —end example ]
换句话说,析构函数由调用函数调用.
In other words, the destructor is invoked by the calling function.
这篇关于传递类按值时,调用方或被调用方是否调用析构函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!