Reputation: 5040
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.
// 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.
// 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.
Upvotes: 1
Views: 257
Reputation: 33126
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.
Upvotes: 1
Reputation: 55887
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.
Upvotes: 2
Reputation: 77304
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.
Upvotes: 0
Reputation: 254481
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.
Upvotes: 1
Reputation: 409196
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.
Upvotes: 0