Подтвердить что ты не робот

Как я могу вызвать функцию 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 уничтожен?

4b9b3361

Ответ 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. Но... вы не можете определить, когда бросать. (Другими словами: вы не знаете, являетесь ли вы сами собой).