重新分配变量时,不会调用析构函数:
Object foo = Object(a,b);
foo = Object(c,d);
因此,析构函数只会在Object(c,d)范围的末尾被调用,这显然会导致问题.现在,在这种特殊情况下,它并没有太多困扰我:它足以声明2个不同的对象:
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);
}
但这对我来说真的很难看,因为我更喜欢在严格必要的时候使用动态分配.我错过了什么吗?
干杯!
Ste*_*sop 11
"析构函数只会在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).实现可以自由执行 - 这是"复制构造函数elision"允许的.
foo = Object(c,d);
(c,d).Object调用类的赋值运算符foo,传递临时参数.一段时间后,在范围的最后,foo被摧毁.
在C++ 0x中,如果类存在,则移动赋值将起作用.
你应该重载赋值运算符,从概念上讲,它会复制构造现有对象并销毁旧的'this'.
class Object {
  ...
  Object& operator= (const Object& other) {
     if (this != &other) {
       // copy 'other' into 'this'.
     }
     return *this;
  }
  ...
};
然后该foo = Object(c,d);线应该做你期望的.
(同样正如@Steve Jessop所提到的,临时对象Object(c,d)也将在范围结束之前被破坏.)
看什么是三规则?.
| 归档时间: | 
 | 
| 查看次数: | 4036 次 | 
| 最近记录: |