如何从析构函数中调用 const 成员函数

How can I call const member function from destructor

当 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 被销毁时没有调用 show 的 const 版本?

const 实例上调用非常量重载的原因是因为在销毁期间不考虑当前实例上的 cv 限定符。 [class.dtor]/p2:

A destructor is used to destroy objects of its class type. The address of a destructor shall not be taken. A destructor can be invoked for a const, volatile or const volatile object. const and volatile semantics (7.1.6.1) are not applied on an object under destruction. They stop being in effect when the destructor for the most derived object (1.8) starts.

您可以使用简单的绑定 *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);
};

我喜欢这个问题。

析构函数不能是常量。它们的行为类似于任何非常量方法。非常量方法调用非常量方法。

但是,有充分的理由在析构函数中调用 const 方法。 (例如记录)。具有从非常量方法调用的非常量和 const 版本,非常量被调用。

要调用常量,可以使用static_cast。但是...您无法确定何时投射。 (换句话说:你不知道自己是否是 const)。

析构函数应该清理它的成员/从某种意义上说,析构函数应该修改当前对象的内容来进行清理。所以,析构函数必须是非常量的。并且,非常量成员函数只能调用所有非常量成员函数。这说明。