Artur Pyszczuk
Artur Pyszczuk

Reputation: 1940

How can I call const member function from destructor

Is there any possible way to invoke const member function from destructor, when const object is destroyed?

Consider:

struct My_type { 
    ~My_type () { 
        show ();
    }

    void show () { 
        cout << "void show ()" << endl;
    }
    void show () const { 
        cout << "void show () const" << endl;
    }
};

And usage:

My_type mt;
const My_type cmt;
mt.show ();
cmt.show ();

Output:

void show ()
void show () const
void show ()
void show ()

Can someone explain me why const version of show has not been invoked when cmt is destroyed?

Upvotes: 27

Views: 1440

Answers (3)

David G
David G

Reputation: 96845

The reason the non-const overload is being called when on a const instance is because cv-qualifiers on the current instance aren't considered during destruction. [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.

You can use a simply bind *this to a reference to const to get the behavior you need:

~My_type() { 
    My_type const& ref(*this);
    ref.show();
}

Or maybe you can use a wrapper that stores a reference and calls show() in its own destructor:

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);
};

Upvotes: 18

Dr. Debasish Jana
Dr. Debasish Jana

Reputation: 7128

Destructor is supposed to do the cleanup of its members/ This, in a sense, destructor is supposed tomodify the contents of the current object whole doing the cleanup. So, destructor has to be non-const. And, a non-const mnember function can call all non-const member function only. This explains.

Upvotes: 3

Bernhard Heinrich
Bernhard Heinrich

Reputation: 120

I like this question.

Destructors can't be const. They behave like any non-const method. A non-const method calls non-const methods.

But, there are good reasons to call const methods in destructors. (Logging for instance). Having both, a non-const and a const version, called from a non-const method, the non-const is called.

To call the const, it is possible to use static_cast. But... you cannot determine when to cast. (In other words: You don't know if you are const yourself).

Upvotes: 2

Related Questions