为什么在静态创建 OBJ 时调用私有析构函数



我问了一个与私有析构函数相关的问题(使用使析构函数私有),但我以下面的问题结束,但我仍然不明白确切的答案。

问题:

为什么当我创建一个具有私有析构函数的类对象时会调用私有析构函数?但当我创建一个普通对象时不会。

案例一

// 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 的对象在程序结束时会超出范围,这正是您在第一个示例中看到的。析构函数声明为私有仅意味着您可以在同一类中创建(和销毁)实例。

虽然我不明白你想实现什么,但错误是显而易见的:

在第一种情况下,构造对象的行位于类内部,因此可以访问所有私有方法。

在第二种情况下,构造在类之外,因此无法访问私有成员。

最新更新