使用使析构函数私有[重复]

Posted

技术标签:

【中文标题】使用使析构函数私有[重复]【英文标题】:Use of making destructor private [duplicate] 【发布时间】:2013-10-26 21:35:41 【问题描述】:

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

    将 MyClass::~MyClass() 析构函数设为私有的用途/原因/好处? 由于析构函数是私有的,所以最后如何调用析构函数。
 // 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++ 如何处理静态案例?是不是覆盖了私人行为?

【问题讨论】:

就输出而言,编译器似乎出错了:该代码 - 就目前而言 - 不应该编译,因为无法调用 dtor。 【参考方案1】:

在共享库的情况下可能会限制应用程序的功能。

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

它就像一个有充分理由的使用合同——它存在于 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() 成员函数应该是公共的,所以这个例子还不够好(它是私有构造函数的一个很好的理由)

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

(编辑:我之前的回答侧重于私有构建,因此我添加了一个更明确的私有销毁示例)

【讨论】:

【参考方案2】:

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

【讨论】:

你能解释一下,谁调用了析构函数?例如在主函数内部,如果我创建 std::string s; 。在这里添加什么魔法编译器来调用析构函数? @dearvivekkumar 也许您应该阅读一些有关 C++ 的知识。这是非常基本的东西:每当一个对象超出范围(当它的生命周期结束时)它的析构函数被调用(在其他情况下也调用析构函数)。尽管源代码不包含对析构函数的显式调用,但这并没有什么神奇之处。 感谢您的建议!但是我有双重原因,即使它是私有的,只有在我创建像“static MyClass __instance;”这样的类实例时才调用析构函数。【参考方案3】:

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

C++ Singleton design pattern

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

What is the lifetime of a static variable in a C++ function?

【讨论】:

【参考方案4】:

是的,在私有部分中创建析构函数是有原因的。它将创建 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;
    

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

【讨论】:

这是一个相当奇怪的推理。 这里没什么奇怪的。这是一个流行的 C++ 习惯用法 - 请参阅 en.wikibooks.org/wiki/More_C%2B%2B_Idioms/…

以上是关于使用使析构函数私有[重复]的主要内容,如果未能解决你的问题,请参考以下文章

在析构函数中捕获异常

C++ 不使用虚析构的后果及分析

受保护的与私有的析构函数

具有私有构造函数和析构函数的类对象的向量?

确定 C++ 类是不是具有私有析构函数

特殊作用的私有成员函数