传递类按值时,调用方或被调用方是否调用析构函数? [英] When passing a class by-value, does the caller or callee call the destructor?

查看:62
本文介绍了传递类按值时,调用方或被调用方是否调用析构函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有以下(经过精简的)代码:

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:

  1. 被调用方(即 foo )在其返回值之前使用其所有按值参数调用析构函数,然后调用方释放内存(通过将其弹出堆栈).
  2. 被叫方不执行任何操作,并且调用方(即 bar )在 foo(p)呼叫.
  1. 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).
  2. 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 the foo(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆