当const对象被销毁时,有没有办法从析构函数中调用const成员函数?
考虑:
struct My_type {
~My_type () {
show ();
}
void show () {
cout << "void show ()" << endl;
}
void show () const {
cout << "void show () const" << endl;
}
};
用法:
My_type mt;
const My_type cmt;
mt.show ();
cmt.show ();
输出:
void show ()
void show () const
void show ()
void show ()
有人可以解释为什么 cmt 被销毁时没有调用const版本的show?
答案 0 :(得分:18)
在const
实例上调用非const重载的原因是因为在销毁期间不考虑当前实例上的cv-qualifiers。 [class.dtor] / P2:
析构函数用于销毁其类类型的对象。不得采用析构函数的地址。 可以为const,volatile或const volatile对象调用析构函数。
const
和volatile
语义(7.1.6.1)不适用于被破坏的对象。当它们停止生效时 最派生对象(1.8)的析构函数启动。
您可以使用简单绑定*this
来引用const
来获取所需的行为:
~My_type() {
My_type const& ref(*this);
ref.show();
}
或许您可以使用存储引用的包装器并在其自己的析构函数中调用show()
:
template<class T>
struct MyTypeWrapper : std::remove_cv_t<T> {
using Base = std::remove_cv_t<T>;
using Base::Base;
T& get() { return ref; }
T const& get() const { return ref; }
~MyTypeWrapper() { ref.show(); }
private:
T& ref = static_cast<T&>(*this);
};
答案 1 :(得分:3)
析构函数应该对其成员进行清理/从某种意义上说,析构函数应该将当前对象的内容整理为清理。因此,析构函数必须是非const的。而且,非const mnember函数只能调用所有非const成员函数。这解释了。
答案 2 :(得分:2)
我喜欢这个问题。
析构函数不能是const。它们的行为与任何非const方法相同。非const方法调用非const方法。
但是,有很好的理由在析构函数中调用const方法。 (例如记录)。具有非const和const版本,从非const方法调用,非const被调用。
要调用const,可以使用static_cast。但是......你无法确定何时施放。 (换句话说:你不知道自己是不是自己)。