使用使析构函数私有[重复]
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
的)及其所有 friend
s 访问。所以,显然,如果你只希望那些能够销毁一个对象,那么制作析构函数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/…以上是关于使用使析构函数私有[重复]的主要内容,如果未能解决你的问题,请参考以下文章