Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deleting object with private destructor

How is that possible that it is allowed to delete object with private destructor in the following code? I've reduced real program to the following sample, but it still compiles and works.

class SomeClass;

int main(int argc, char *argv[])
{
  SomeClass* boo = 0; // in real program it will be valid pointer
  delete boo; // how it can work?

  return -1;
}

class SomeClass
{
private:
  ~SomeClass() {}; // ! private destructor !
};
like image 647
big-z Avatar asked Oct 23 '09 06:10

big-z


People also ask

Does destructor delete object?

Destructors are usually used to deallocate memory and do other cleanup for a class object and its class members when the object is destroyed. A destructor is called for a class object when that object passes out of scope or is explicitly deleted.

What happens when a destructor is private?

Private Destructor in C++ This code has private destructor, but it will not generate any error because no object is created.

Can we have destructor as private?

Destructors with the access modifier as private are known as Private Destructors. Whenever we want to prevent the destruction of an object, we can make the destructor private.

Do destructors have to be public?

There's nothing inherently wrong with making the destructor protected or private, but it restricts who can delete the pointer.


3 Answers

You are trying to delete object of incomplete class type. C++ Standard says that you'll get undefined behavior in this case (5.3.5/5):

If the object being deleted has incomplete class type at the point of deletion and the complete class has a non-trivial destructor or a deallocation function, the behavior is undefined.

To detect such cases you could use boost::checked_delete:

template<typename T> 
inline void checked_delete( T* p )
{
    typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
    (void) sizeof(type_must_be_complete);
    delete p;
}
like image 65
Kirill V. Lyadvinsky Avatar answered Oct 10 '22 03:10

Kirill V. Lyadvinsky


This code causes undefined behavior (UB). It is UB in C++ to delete an object of incomplete type having a non-trivial destructor. And in your code the type SomeClass is incomplete at the point of delete, and it has a non-trivial destructor. Compilers usually issue a warning about this, since in C++ formally this is not a constraint violation.

So, strictly speaking, your code doesn't "work". It simply compiles and does something undefined when run.

The compiler is just not required to catch this error. The reason for this is that this could be perfectly fine if your object has a trivial destructor. The compiler has no way of knowing what kind of destructor this type will eventually have, so it can't say for sure whether this is an error or not.

like image 21
AnT Avatar answered Oct 10 '22 03:10

AnT


Because SomeClass type is not completely declared when invoking operator delete.

Deleting such a pointer is undefined behavior, but in practice most compilers would just free the memory (if the pointer was non-NULL) and not call the destructor.

For example, g++ will give you a warning about this issue:

foo.cpp: In function 'int main(int, char**)':
foo.cpp:6: warning: possible problem detected in invocation of delete operator:
foo.cpp:5: warning: 'boo' has incomplete type
foo.cpp:1: warning: forward declaration of 'struct SomeClass'
foo.cpp:6: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined.
like image 39
laalto Avatar answered Oct 10 '22 01:10

laalto