Как я могу вызвать функцию const member из деструктора
Есть ли какой-либо возможный способ вызвать функцию const member из деструктора, когда объект 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 ()
Может кто-нибудь объяснить мне, почему версия версии show не была вызвана, когда cmt уничтожен?
Ответы
Ответ 1
Причина того, что неконстантная перегрузка вызывается, когда экземпляр const
- это потому, что cv-квалификаторы в текущем экземпляре не рассматриваются во время уничтожения. [Class.dtor]/р2
Деструктор используется для уничтожения объектов своего типа класса. Адрес деструктора не должен приниматься. Деструктор может быть вызван для 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);
};
Ответ 2
Деструктор должен выполнять очистку своих членов/Это, в определенном смысле, деструктор допускает томодизацию содержимого текущего объекта, выполняющего очистку. Итак, деструктор должен быть неконстантным. И функция non-const mnember может вызывать все не-константные функции-члены. Это объясняет.
Ответ 3
Мне нравится этот вопрос.
Деструкторы не могут быть const. Они ведут себя как любой неконстантный метод. Метод non-const вызывает неконстантные методы.
Но есть веские причины для вызова методов const в деструкторах. (Например, ведение журнала). Имея обе версии non-const и const, вызываемые из неконстантного метода, вызывается non-const.
Чтобы вызвать const, можно использовать static_cast. Но... вы не можете определить, когда бросать. (Другими словами: вы не знаете, являетесь ли вы сами собой).