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

时间:2015-04-08 17:04:19

标签: c++ c++11 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 被销毁时没有调用const版本的show?

3 个答案:

答案 0 :(得分:18)

const实例上调用非const重载的原因是因为在销毁期间不考虑当前实例上的cv-qualifiers。 [class.dtor] / P2:

  

析构函数用于销毁其类类型的对象。不得采用析构函数的地址。   可以为const,volatile或const volatile对象调用析构函数。 constvolatile   语义(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。但是......你无法确定何时施放。 (换句话说:你不知道自己是不是自己)。