重新分配变量时,不调用析构函数:

Object foo = Object(a,b);
foo = Object(c,d);

因此,析构函数只会在Object(c,d)作用域的末尾被调用,这显然会引起问题。
现在,在这种特定情况下,它并不过分困扰我:声明两个不同的对象就足够了:
Object foo1 = Object(a,b);
Object foo2 = Object(c,d);

这样,两个对象的析构函数将在最后被调用。

但是,在某些情况下,我必须需要重新分配变量,即在诸如以下的对象构造函数中:
SuperObject(Point point1, Point point2) : delay_object_(DelayObject(0)) {
  double distance = distance(point1, point2);
  double delay = distance / speed;

  delay_object_ = DelayObject(delay);
}

实际上,DelayObject参数不容易计算(在此示例中,我还省略了其他几段内容),并且我想避免在初始化列表中使用它。

我以为可以通过将对象放入堆并显式调用析构函数来强制删除:
SuperObject(Point point1, Point point2) : p_delay_object_(new DelayObject(0)) {
  double distance = distance(point1, point2);
  double delay = distance / speed;

  delete p_delay_object_;
  p_delay_object_ = new DelayObject(delay);
}

但这对我来说确实很难看,因为我更喜欢仅在严格必要时才使用动态分配。我想念什么吗?

干杯!

最佳答案

“析构函数将仅在Object(c,d)作用域的末尾被调用”

假。 Object(c,d)是临时的,其析构函数在创建它的完整表达式的末尾被调用。在这种情况下,这就是foo = Object(c,d);末尾的分号。范围结束时调用foo的析构函数。
Object的赋值运算符应释放或重新使用foo已拥有的资源,并复制临时资源所拥有的资源。不一定按此顺序排列(请参阅 copy-and-swap )。

编辑:回应评论。

Object foo = Object(a,b);

要么
  • 使用匹配(a,b)的任何两个参数的构造函数构造一个临时目录。
  • foo是使用copy-constructor构造的,并传递了临时变量作为参数。
  • 临时目录被销毁。

  • 要么
  • foo使用匹配(a,b)的任何两个参数的构造函数构造。

  • 该实现可以任意执行-“复制构造函数省略”允许这样做。
    foo = Object(c,d);
    
  • 使用匹配(c,d)的任何两个参数的构造函数构造一个临时目录。
  • Object上调用foo类的赋值运算符,并将临时变量作为参数传递。
  • 临时目录被销毁。

  • 一段时间后,在作用域末尾,foo被销毁。

    在C++ 0x中,如果该类存在移动分配,它将发挥作用。

    07-24 09:46
    查看更多