1

I have asked one question (Use of making destructor private) related with private destructor, but I have ended with this below question and still I don't understand the exact answer.

Question:

Why private destructor are getting called when I creates an object of class having private destructor? But not when I creates a normal object.

CASE I

// 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 
main finished
Destructor.

CASE II

// myclass.h

#include <iostream>

class MyClass {
public:
    void Display();
    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 testObj;



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

    return 0;
}

// Error
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

EDIT

I have come to know that making destructor protected/private is needed when we "Require heap based object only.

http://en.wikibooks.org/w/index.php?title=More_C%2B%2B_Idioms%2FRequiring_or_Prohibiting_Heap-based_Objects&diff=2567824&oldid=2202430&utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+MoreCppIdiomsWikibook+%28Wikibooks+-+Changes+related+to+%22More+C%2B%2B+Idioms%22+[en]%29

Community
  • 1
  • 1
Vivek Kumar
  • 4,822
  • 8
  • 51
  • 85
  • The error you get in the 2. case suggests that you are using the header file from your 1. case. If you used the header file you claim to use, you should get an error about GetInstance() being undeclared instead of the constructor/destructor. So double check your setup. – nos Oct 21 '13 at 11:02

5 Answers5

2

Static function is function of class, so it has access to private functions of this class, thats why 1 case work well as expected.

In first case - object will be created in function Instance, which have access to constructor for this class. Since object is declared static - it will be destroyed only in the end of program, since object is created in class function - there is access to destructor.

In second case - you are trying to create object of type MyClass in main function, which is not class-function, so it has no access to c-tor/d-tor.

ForEveR
  • 55,233
  • 2
  • 119
  • 133
  • Meaning private, public and protected are compiler time constraint...right. Please correct me if I am trying of forming wrong concept. Because wherever object goes out of scope, compiler, at the time of compilation, must have added code underneath for calling destructor? If this is correct, this means that compiler must have called it's destructor when program was terminating, and static variables were going out of scope. – Vivek Kumar Oct 21 '13 at 11:16
  • @dearvivekkumar think about your first case like, construct static object in function and destruct this object also in function, since there is access to d-tor/c-tor. – ForEveR Oct 21 '13 at 11:23
  • Yes, I am trying my best. But When I call GetInstance() then that function is over, it's stack will be poped off. So destructor must have called outside of any function of MyClass. But I thanks for your time and explanation so far. :) – Vivek Kumar Oct 21 '13 at 11:26
  • @dearvivekkumar true. Really, probably there are two functions (constructor/destructor) in global scope. Since static variables creation/destruction is performed in runtime - they can actually construct/destruct, since there is no access rules in runtime. – ForEveR Oct 21 '13 at 11:42
1

In both cases, the destructor is needed to destroy the object at the end of its static or automatic lifetime, so must be accessible where the object is declared.

In the first case, the object is declared inside a member of the class, so the destructor is accessible and compilation succeeds.

In the second case, the object is declared in a non-member function, so the destructor is no accessible and compilation fails.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
1

An object with static storage duration is destroyed after a return from main or after a call to std::exit. Section 3.6.3 of the standards describe this destruction. From C++11, 3.6.3,

Destructors for initialized objects (that is, objects whose lifetime has begun) with static storage duration are called as a result of returning from main and as a result of calling std::exit.

Note that there is no mention of the accessibility (public/protected/private) of the destructor. The appropriate destructor is called, period.

It's section 12.4 that covers accessibility. C++11 12.4 para 11 (paragraph 10 in C++03) states that

A program is ill-formed if an object of class type or array thereof is declared and the destructor for the class is not accessible at the point of the declaration.

The destructor is accessible in static function MyClass::GetInstance(), so the block scope static variable declared in that function is okay. The destructor is not accessible in main(), so the automatic variable declared in main is not okay.

David Hammen
  • 32,454
  • 9
  • 60
  • 108
0

All objects are destructed when they go out of scope, and objects declared static goes out of scope when the program ends, which is exactly what you see in the first example. That the destructor is declared as private only means that you can create (and destroy) instances within the same class.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

Although I don't understand what you are trying to achive, the error is obvious:

In your first case, the line constructing your object is inside the class and therefor has access to all private methods.

In your second case, the construction is outside the class and therefor no access to private members is possible.

nvoigt
  • 75,013
  • 26
  • 93
  • 142