2

在下面的代码中,我没有得到

  1. 将 MyClass::~MyClass() 析构函数设为私有的用途/原因/好处?
  2. 由于析构函数是私有的,所以最后如何调用析构函数。
 // 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;
}

//输出

Constructor
Hello
Destructor

// 编辑

如果我公开我的类的构造函数并删除 GetInstance() 函数。

> MyClass obj;
> obj.Display();

然后弹出如下错误

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

'

问题:如何让 C++ 处理静态案例?是不是覆盖了私人行为?

4

4 回答 4

2

在共享库的情况下,它可能会限制应用程序可以做什么。

使用共享库的应用程序使用导出函数来获取对象的句柄,并且必须显式调用另一个导出函数来销毁对象。

它就像一个有充分理由的使用合同——它存在于 DLL/so 的堆或数据段中——因此应用程序无法释放它)。

该导出的函数又会调用您的静态函数。就像是:

extern "C" __declspec(dllexport) MyClass* CreateMyClass() {
    return &MyClass::GetInstance();
}


extern "C" __declspec(dllexport) void     DestroyMyClass(MyClass* handle) {
    delete handle; // assumes destructor isn't private. 
    // if destructor is private, you can't use delete since it calls the destructor, which is .... private!
    handle->Destroy(); // A member function that calls the private destructor
}

MyClass::Destroy() {
    if (it_is_safe_to_destroy_the_class)
        ~Destroy();
}

但是,那么 Destroy() 成员函数应该是公共的,所以这个例子还不够好(它是私有构造函数的一个很好的理由)

从本质上讲,您希望限制您的班级的用户可以通过私有构造和/或销毁来执行的操作。您通过静态变量“创建”实例,而不是它们,并允许它们仅使用功能(公共接口)而不是其他任何东西。同样,当您认为它安全时,您将其销毁。

(编辑:我之前的回答侧重于私人建设,所以我添加了一个更明确的私人销毁示例)

于 2013-10-18T06:36:42.113 回答
0

类本身及其所有s的所有成员函数(包括成员函数)都可以访问private析构函数。所以,很明显,如果你只希望那些能够销毁一个对象,那么制作析构函数就是要走的路。staticfriendprivate

于 2013-10-18T06:43:38.920 回答
0

您发布的类看起来像一个单例,这是一个每次执行只允许实例化一次的类。构造函数和析构函数都是私有的,以确保您可以访问对象实例的唯一方法是通过 GetInstance 调用,该调用以确保只有一个实例存在的方式编写。

C++ 单例设计模式

在您的实现中,实例是一个静态对象,这意味着当您的程序清理静态对象时,它将被删除,基本上是在程序结束时。

C++ 函数中静态变量的生命周期是多少?

于 2013-10-18T06:52:33.853 回答
-1

是的,在私有部分中创建析构函数是有原因的。它将创建
只能动态分配对象的 C++ 类。

你可以举这个例子:

 #include <iostream>
  using namespace std;

  // A class whose object can only be dynamically created
  class Test
     {
      private:
        ~Test() { cout << "Destroying Object\n"; }
      public:
        Test() { cout << "Object Created\n"; }
        friend void destructTest(Test* );
 };

// Only this function can destruct objects of Test
  void destructTest(Test* ptr)
    {
delete ptr;
cout << "Object Destroyed\n";
}

  int main()
     {
   /* Uncommenting following following line would cause compiler error */
   // Test t1;

 // create an object
     Test *ptr = new Test;

 // destruct the object to avoid memory leak
destructTest(ptr);

return 0;
    }

如果您尝试创建静态对象,编译器会报错

于 2013-10-18T06:34:59.070 回答