为什么在静态创建 OBJ 时调用私有析构函数
why private destructor getting called when obj is created statically
我问了一个与私有析构函数相关的问题(使用使析构函数私有),但我以下面的问题结束,但我仍然不明白确切的答案。
问题:
为什么当我创建一个具有私有析构函数的类对象时会调用私有析构函数?但当我创建一个普通对象时不会。
案例一
// 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:programscpp_testsrcmain.cpp(38): error C2248: 'MyClass::MyClass' : cannot access private member declared in class 'MyClass'
1> e:programscpp_teststatic_single_test.h(11) : see declaration of 'MyClass::MyClass'
1> e:programscpp_teststatic_single_test.h(6) : see declaration of 'MyClass'
1>e:programscpp_testsrcmain.cpp(38): error C2248: 'MyClass::~MyClass' : cannot access private member declared in class 'MyClass'
1> e:programscpp_teststatic_single_test.h(12) : see declaration of 'MyClass::~MyClass
编辑
我已经知道,当我们"仅需要基于堆的对象"时,需要使析构函数受保护/私有。
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
静态函数是类的函数,因此它可以访问该类的private
函数,这就是为什么 1 个案例按预期工作的原因。
在第一种情况下 - 对象将在函数 Instance
中创建,该函数可以访问此类的构造函数。由于对象是static
声明的 - 它只会在程序结束时被销毁,因为对象是在类函数中创建的 - 可以访问析构函数。
在第二种情况下 - 您正在尝试在函数中创建 MyClass
类型的对象main
该函数不是类函数,因此它无法访问 c-tor/d-tor。
在这两种情况下,都需要析构函数在其静态或自动生存期结束时销毁对象,因此必须在声明对象的位置可访问。
在第一种情况下,对象在类的成员中声明,因此析构函数是可访问的,编译成功。
在第二种情况下,对象在非成员函数中声明,因此析构函数不可访问,编译失败。
静态存储持续时间的对象在从main
返回或调用std::exit
后被销毁。标准第3.6.3节描述了这种销毁。从 C++11、3.6.3 开始,
具有静态存储持续时间的初始化对象(即生存期已开始的对象)的析构函数由于从 main 返回和调用 std::exit 而被调用。
请注意,没有提到析构函数的可访问性(公共/受保护/私有)。相应的析构函数称为 period。
这是第 12.4 节,涵盖了辅助功能。C++11 12.4 第11段(C++03)第10段指出:
如果声明了类类型的对象或其数组,并且在声明点无法访问该类的析构函数,则程序格式不正确。
析构函数可以在静态函数MyClass::GetInstance()
中访问,因此在该函数中声明的块范围静态变量是可以的。析构函数在main()
中无法访问,因此在 main
中声明的自动变量是不行的。
所有对象在超出范围时都会被销毁,声明为 static 的对象在程序结束时会超出范围,这正是您在第一个示例中看到的。析构函数声明为私有仅意味着您可以在同一类中创建(和销毁)实例。
虽然我不明白你想实现什么,但错误是显而易见的:
在第一种情况下,构造对象的行位于类内部,因此可以访问所有私有方法。
在第二种情况下,构造在类之外,因此无法访问私有成员。
- 什么时候调用析构函数
- C++-明确何时以及如何调用析构函数
- C++ 防止在映射中放置()时调用析构函数
- 调用析构函数以释放动态分配的内存
- C++:使用方法调用析构函数的顺序是什么?
- 向量推回调用析构函数时调用析构函数
- 如何在调用析构函数时优雅地停止/销毁带有阻塞调用C++线程?
- C++,我应该调用析构函数吗?
- 如何获取有关在 Clang LibTooling 中调用析构函数的信息?
- 当我从 std::vector 中的新放置调用析构函数时会发生什么?
- 为什么这里不调用析构函数
- 在调用 std::bind 的产品后意外调用析构函数
- 为什么在传递给函数而不是构造函数时调用析构函数?
- 如何在C++中调用析构函数
- 为什么为未删除的对象调用析构函数?
- 调用析构函数时出错
- C++ 在不释放内存的情况下调用析构函数
- 为什么在运算符删除中不调用析构函数?
- C++ 调用析构函数后动态模板队列"double free or corruption (out)"
- 在 postOrderDelete 上调用析构函数时引发的异常