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

时间:2015-01-28 12:39:43

标签: c++ c++11 scope destructor

我有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);
}

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

1 个答案:

答案 0 :(得分:6)

您正在创建Apple类型的临时文件。它超出了表达式的范围,它是它的一部分 - 这是赋值语句。当它超出范围时,析构函数将被调用。 FruitApple之间的层次关系与此无关。

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

if (settings.has_domain_socket()) {
    listener = Apple(settings);
}

基本上等同于:

if (settings.has_domain_socket()) {
    Apple some_temporary_apple(settings);
    listener = std::move(some_temporary_apple);
}

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

另请注意:

Fruit f = Apple();

将执行object slicing,这使其成为一种反模式。