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

时间:2013-10-21 10:57:17

标签: c++ constructor

我问了一个与私有析构函数相关的问题(Use of making destructor private),但我已经以下面的问题结束了,但我仍然不明白答案。

问题:

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

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

修改

我已经知道当我们“只需要基于堆的对象时”需要使析构函数受保护/私有。

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]%2 9

5 个答案:

答案 0 :(得分:2)

静态函数是类的函数,因此它可以访问此类的private函数,这就是为什么1个案例可以正常工作的原因。

在第一种情况下 - 将在函数Instance中创建对象,该对象可以访问此类的构造函数。由于object被声明为static - 它只会在程序结束时被销毁,因为对象是在类函数中创建的 - 可以访问析构函数。

在第二种情况下 - 您试图在MyClass函数中创建类型main的对象,这不是类函数,因此它无法访问c-tor / d-tor。 / p>

答案 1 :(得分:1)

main返回或致电std::exit后,具有静态存储持续时间的对象将被销毁。标准的第3.6.3节描述了这种破坏。来自C ++ 11,3.6.3,

  

具有静态存储持续时间的初始化对象(即,其生命周期已开始的对象)的析构函数被调用为从main返回并且由于调用std :: exit而被调用。

请注意,没有提到析构函数的可访问性(public / protected / private)。适当的析构函数叫做句点。

第12.4节涵盖了可访问性。 C ++ 11 12.4第11段(C ++ 03第10段)指出

  

如果声明了类类型的对象或其数组,并且在声明时无法访问该类的析构函数,则程序格式不正确。

析构函数可以在静态函数MyClass::GetInstance()中访问,因此在该函数中声明的块作用域静态变量是可以的。 main()中无法访问析构函数,因此main中声明的自动变量不正常。

答案 2 :(得分:0)

当超出范围时,所有对象都被破坏,并且当程序结束时,声明为static的对象超出范围,这正是您在第一个示例中看到的。析构函数声明为private只意味着您可以在同一个类中创建(和销毁)实例。

答案 3 :(得分:0)

在这两种情况下,析构函数都需要在静态或自动生命周期结束时销毁对象,因此必须可以在声明对象的地方访问它。

在第一种情况下,对象在类的成员内声明,因此可以访问析构函数并编译成功。

在第二种情况下,对象在非成员函数中声明,因此析构函数不可访问,编译失败。

答案 4 :(得分:0)

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

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

在你的第二个案例中,构造不在课堂之内,因此无法访问私人成员。