变量范围混淆 - 析构函数意外调用

rui*_*eco 1 c++ destructor scope c++11

我有3个课程,水果,苹果和橘子,水果是两者的父母.我有一个静态方法,我在其中执行以下操作:

int32_t Fruit::frutificate(const Settings& settings) {
  Fruit listener;
  if (settings.has_domain_socket()) {
    listener = Apple(settings);
  } else {
    listener = Orange(settings);
  }
  return uv_run(listener.loop, UV_RUN_DEFAULT);
}
Run Code Online (Sandbox Code Playgroud)

令我困惑的是Apple的析构函数,它运行清理代码Fruit没有的,在这种条件下调用.苹果是水果和水果的孩子是在条件之外宣布的,所以在返回之前,范围不应该持续吗?

Bar*_*rry 6

您正在创建临时类型Apple.它超出了表达式的范围,它是它的一部分 - 这是赋值语句.当它超出范围时,析构函数将被调用.之间的层次关系Fruit,并Apple在这里无关紧要.

如果它有帮助,你可以想到这个块:

if (settings.has_domain_socket()) {
    listener = Apple(settings);
}
Run Code Online (Sandbox Code Playgroud)

基本相当于:

if (settings.has_domain_socket()) {
    Apple some_temporary_apple(settings);
    listener = std::move(some_temporary_apple);
}
Run Code Online (Sandbox Code Playgroud)

这可能会更清楚地说明为什么~Apple()在作业结束时被调用.

另请注意:

Fruit f = Apple();
Run Code Online (Sandbox Code Playgroud)

将执行对象切片,这使其成为反模式.