C++ 未使用智能指针或原始指针调用析构函数

C++ 未使用智能指针或原始指针调用析构函数,c++,c++11,C++,C++11,从a继续: 在这段代码中,苹果和水果的析构函数根本不会被调用。我在两者中都有std::cerr语句,而且苹果中有一些清理代码没有运行。我觉得打电话删除就够了?我做得对吗?我还用std::unique_ptr替换了原始指针,得到了相同的结果 int32_t Fruit::frutificate(const Settings& settings) { Fruit *listener; if (settings.has_domain_socket()) { listener =

从a继续:

在这段代码中,苹果和水果的析构函数根本不会被调用。我在两者中都有std::cerr语句,而且苹果中有一些清理代码没有运行。我觉得打电话删除就够了?我做得对吗?我还用std::unique_ptr替换了原始指针,得到了相同的结果

int32_t Fruit::frutificate(const Settings& settings) {
  Fruit *listener;
  if (settings.has_domain_socket()) {
    listener = new Apple(settings);
  } else {
    listener = new Orange(settings);
  }
  int r = uv_run(listener->loop, UV_RUN_DEFAULT);
  delete listener;
  return r;
}
更新:
所有类都有虚拟析构函数。

首先,您的直接问题几乎肯定是~Fruit不是虚拟的。将virtual~Fruit=default或virtual~Fruit{}添加到类Fruit中,您发布的代码将神奇地开始工作

然而,这不是你的代码应该是什么。只是工作,还不够好

您可以对代码进行许多改进。作为第一项改进,我们将使用上述注释中提到的独特的_ptr:As@Deduplicator

int32_t Fruit::frutificate(const Settings& settings) {
  std::unique_ptr<Fruit> listener;
  if (settings.has_domain_socket()) {
    listener.reset( new Apple(settings) );
  } else {
    listener.reset( new Orange(settings) );
  }
  int r = uv_run(listener->loop, UV_RUN_DEFAULT);
  return r;
}
它的缺点是重复uv_运行代码,因此会滋生bug。我们可以用lambda解决这个问题:

int32_t Fruit::frutificate(const Settings& settings) {
  auto fruit_the_uv = [&](Fruit&& fruit) {
    return uv_run(fruit.loop, UV_RUN_DEFAULT);
  };
  if (settings.has_domain_socket()) {
    return fruit_the_uv( Apple(settings) );
  } else {
    return fruit_the_uv( Orange(settings) );
  }
}
我们将公共代码分解成一个lambda,然后在两个分支上调用它。我在传递临时水果时使用了右值引用


另外,每当我读到它时,紫外线会让我想起一种水果。这是一个加号。

水果有虚拟析构函数吗?您有未定义的行为,可能表现为未能以其他方式调用正确的析构函数。@重复数据消除程序:或甚至没有指针:int32_t Fruit::FrutificteConst设置和设置{if Settings.has_domain_socket{return uv_runApplesettings.loop,uv_RUN_DEFAULT;}否则{return uv runorrangesettings.loop,uv RUN___DEFAULT;}所有的课程都包括水果吗。。。我知道一个愚蠢的问题,请耐心听我说,没有完整的类定义,真的什么都说不出来。这个问题离主题关闭只有一票之遥,请添加必要的信息让我们回答它,这意味着至少水果的析构函数声明,最好是否定的,所有的析构函数都是虚拟的。我知道我可以用你的lambda解决这个问题,但我现在很好奇为什么析构函数不起作用。@lapinrigolo,因为你传递的是临时变量,临时变量不绑定左值引用。所以我使用了右值引用。如果const&可以工作,也就是说,如果uv_与const循环一起运行,那么您可以使用它。在C++14中,我只使用一个转发引用auto&&可能。-水果有一个显式析构函数,它是虚拟的?发布水果的实际析构函数。virtual~Fruit;-实现是空的。
int32_t Fruit::frutificate(const Settings& settings) {
  auto fruit_the_uv = [&](Fruit&& fruit) {
    return uv_run(fruit.loop, UV_RUN_DEFAULT);
  };
  if (settings.has_domain_socket()) {
    return fruit_the_uv( Apple(settings) );
  } else {
    return fruit_the_uv( Orange(settings) );
  }
}