我知道不允许修改常量对象的状态,但是为什么析构函数可以更改此状态?
class A
{
public:
~A()
{
i = 2; //?
}
void test() const
{
//i = 1; //Not allowed
}
int i = 0;
};
int main()
{
const A o;
o.test();
}
答案 0 :(得分:21)
为什么析构函数可以更改此状态?
因为能够更改析构函数中的对象是否为const可能是有用的。
并且因为封装无关紧要。生命周期已经结束,因此任何人都无法看到处于修改状态的对象。
而且由于标准(引自草案)是这样的:
[class.dtor]
不应该使用析构函数的地址。 可以为const,volatile或const volatile对象调用析构函数。 const和volatile语义([dcl.type.cv])不会应用于正在破坏的对象。 当最派生对象([intro.object])的析构函数启动时,它们停止生效。
答案 1 :(得分:7)
一旦执行了析构函数,对象的生存期就已经结束。禁止修改状态的操作没有任何意义,因为作为行为良好的代码一部分的任何调用者都不会看到这种修改后的状态。另外,生命周期结束后,对象是否已预先const
都无关紧要。这与构造函数不是const
限定的特殊成员函数的原因相同。他们在对象的生存期之前设置了对象。只要它还活着,就可以事先为const
,这毫无意义,而且价值不大。
答案 2 :(得分:2)
出于相同的原因,构造函数可以更改状态!这两个方法拥有该对象,并且可以执行他们喜欢的任何操作来创建和销毁它。
尤其是,对象可能具有一些已分配的资源,或包含智能指针。这些必须由销毁者销毁。
请耐心等待,直到找到有关可变成员和rval引用的信息!