Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 958
Artur Pyszczuk Avatar asked Apr 08 '15 17:04

Artur Pyszczuk


People also ask

Can destructor call member function?

No. You never need to explicitly call a destructor (except with placement new ). A class's destructor (whether or not you explicitly define one) automagically invokes the destructors for member objects. They are destroyed in the reverse order they appear within the declaration for the class.

How do you call a constant member function in C++?

Const member functions in C++ The object called by these functions cannot be modified. It is recommended to use const keyword so that accidental changes to object are avoided. A const member function can be called by any type of object.

Can a destructor be const?

Constructors and destructors can never be declared to be const . They are always allowed to modify an object even if the object itself is constant.

Can we call non-const member function from const member function?

A const object can be created by prefixing the const keyword to the object declaration. Any attempt to change the data member of const objects results in a compile-time error. When a function is declared as const, it can be called on any type of object, const object as well as non-const objects.


1 Answers

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); }; 
like image 65
David G Avatar answered Sep 23 '22 12:09

David G