2

In the code below, I am not getting the

  1. use/reasons/benefits of making MyClass::~MyClass() destructor private?
  2. Since the destructor is private, so how the destructor are getting called at the end.
 // myclass.h
#include <iostream>
class MyClass {
public:
    static MyClass& GetInstance();
    void Display();
private:
    MyClass();
    virtual ~MyClass();
};
MyClass::MyClass() {
    std::cout << "Constructor " << std::endl;
}

MyClass::~MyClass() {
    std::cout << "Destructor" << std::endl;
}

MyClass& MyClass::GetInstance() {
    static MyClass _instance;
    return _instance;
}

void MyClass::Display() {
    std::cout << "Hello" << std::endl;
}

// main.cpp

#include "myclass.h"
#include <iostream>
int main() {

    MyClass::GetInstance().Display(); //case1



    std::cout << "main finished!" << std::endl;

    return 0;
}

//Output

Constructor
Hello
Destructor

// Edit

if I make the Contructor of my class public and remove the GetInstance() function.

> MyClass obj;
> obj.Display();

Then the following error pops up

1>e:\programs\cpp_test\src\main.cpp(38): error C2248: 'MyClass::MyClass' : cannot access private member declared in class 'MyClass'
1>          e:\programs\cpp_test\static_single_test.h(11) : see declaration of 'MyClass::MyClass'
1>          e:\programs\cpp_test\static_single_test.h(6) : see declaration of 'MyClass'
1>e:\programs\cpp_test\src\main.cpp(38): error C2248: 'MyClass::~MyClass' : cannot access private member declared in class 'MyClass'
1>          e:\programs\cpp_test\static_single_test.h(12) : see declaration of 'MyClass::~MyClass

'

Question: How making how static case is being handled by c++? Is is not overriding the private behaviour?

Vivek Kumar
  • 4,822
  • 8
  • 51
  • 85
  • As far the output is, it looks like the compiler did a fault: that code -as it stand- should not compile since the dtor cannot be called. – Emilio Garavaglia Oct 18 '13 at 06:33

4 Answers4

2

It might come up in the case of shared libraries to limit what an application can do.

The application using the shared library uses an exported function to get a handle to the object and has to explicitly call another exported function to destroy the object.

Its like a contract of usage with good reason - it exists in the DLL/so 's heap or data segment - so the application can't deallocate it).

That exported function in turn would call your static function. Something like:

extern "C" __declspec(dllexport) MyClass* CreateMyClass() {
    return &MyClass::GetInstance();
}


extern "C" __declspec(dllexport) void     DestroyMyClass(MyClass* handle) {
    delete handle; // assumes destructor isn't private. 
    // if destructor is private, you can't use delete since it calls the destructor, which is .... private!
    handle->Destroy(); // A member function that calls the private destructor
}

MyClass::Destroy() {
    if (it_is_safe_to_destroy_the_class)
        ~Destroy();
}

But, then the Destroy() member function ought to be public, so this example isn't good enough (it served as a good reason for private constructor)

Essentially, you want to limit what users of your class can do via private construction and/or destruction. You "create" the instance, not them, via a static variable and allow them to only use the functionality (public interface) and not anything else. Similarly, you destroy it when you deem it safe.

(Edit: My previous answer was focused towards private construction, so I added a more explicit example for private destruction)

Raja
  • 2,846
  • 5
  • 19
  • 28
0

A private destructor is accessible by all member functions (including static ones) of the class itself and all its friends. So, obviously, if you only want those to be able to destroy an object, then making the destructor private is the way to go.

Walter
  • 44,150
  • 20
  • 113
  • 196
  • Can you please explain, who call the destructor? For example inside the main function, If I create { std::string s; }. What magic compiler add here to call the destructor? – Vivek Kumar Oct 18 '13 at 06:47
  • @dearvivekkumar Perhaps you should read up a little on C++. This is very basic stuff: whenever an object goes out of scope (when its lifetime ends) its destructor is called (the desctructor is also called in other circumstances). There is nothing magical about that, though the source code does not contain an *explicit* call to the destructor. – Walter Oct 19 '13 at 10:22
  • Thanks for the suggestions! But I have double why the destructor is being called even though it is private only in case when I create the class instance like "static MyClass __instance;". – Vivek Kumar Oct 21 '13 at 04:46
0

The class you posted looks like a singleton, which is a class that is only allowed to be instanced once per execution. Both the constructor and destructor are made private, to make sure the only way you can access an instance of the object is via the GetInstance call, which is written in such a way as to ensure only one instance will exist.

C++ Singleton design pattern

With your implementation, the instance is a static object, which means it will be deleted when static objects are cleaned up by your program, basically when the program ends.

What is the lifetime of a static variable in a C++ function?

Community
  • 1
  • 1
Kindread
  • 926
  • 4
  • 12
-1

Yes, There is a reason to make the destructor in private section.It will create C++ class
whose objects can only be dynamically allocated.

you can take this example:

 #include <iostream>
  using namespace std;

  // A class whose object can only be dynamically created
  class Test
     {
      private:
        ~Test() { cout << "Destroying Object\n"; }
      public:
        Test() { cout << "Object Created\n"; }
        friend void destructTest(Test* );
 };

// Only this function can destruct objects of Test
  void destructTest(Test* ptr)
    {
delete ptr;
cout << "Object Destroyed\n";
}

  int main()
     {
   /* Uncommenting following following line would cause compiler error */
   // Test t1;

 // create an object
     Test *ptr = new Test;

 // destruct the object to avoid memory leak
destructTest(ptr);

return 0;
    }

If you try to crate a static object compiler gives an error

Birendra Kumar
  • 431
  • 1
  • 7
  • 18