重新分配变量时,不调用析构函数:
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中,如果该类存在移动分配,它将发挥作用。