将析构函数作为私有的用途是什么?
将析构函数作为私有的用途是什么?
基本上,任何时候你想要一些其他的类来负责你的类的对象的生命周期,或者你有理由防止对象的破坏,你可以使析构函数是私有的。
例如,如果你正在做某种引用计数的事情,你可以让这个对象(或者说是“朋友”的pipe理者)负责计算引用的数量,当数字为零时删除它。 一个私人的dtor会阻止其他人删除它,当还有引用它的时候。
再举一个例子,如果你有一个对象有一个pipe理者(或者它本身)可能会破坏它,或者根据程序中的其他条件(例如正在打开的数据库连接或正在写入的文件)拒绝销毁它。 你可以在类或者pipe理器中有一个“request_delete”方法来检查这个条件,它会删除或者拒绝,并返回一个状态来告诉你它做了什么。 这更加灵活,只是调用“删除”。
这样的对象不能在堆栈上创build。 总是在堆上。 删除必须通过朋友或成员完成。 产品可以使用单个对象层次结构和自定义内存pipe理器 – 这种场景可以使用私有的dtor。
#include <iostream> class a { ~a() {} friend void delete_a(a* p); }; void delete_a(a* p) { delete p; } int main() { a *p = new a; delete_a(p); return 0; }
当你不想让用户访问析构函数的时候,也就是说,你希望对象只能通过其他方式被销毁。
COM使用此策略删除实例。 COM使析构函数保密,并提供一个用于删除实例的接口。
下面是Release方法的一个例子。
int MyRefCountedObject::Release() { _refCount--; if ( 0 == _refCount ) { delete this; return 0; } return _refCount; }
ATL COM对象是这种模式的主要例子。
这个类只能被自己删除。 有用的,如果你正在创造一些引用计数对象的尝试。 那么只有释放方法可以删除对象,可能帮助你避免错误。
增加在这里已经存在的答案; 私有构造函数和析构函数在实现创build对象需要在堆上分配的工厂时非常有用。 一般而言,这些对象将由静态成员或朋友创build/删除。 一个典型用法的例子:
class myclass { public: static myclass* create(/* args */) // Factory { return new myclass(/* args */); } static void destroy(myclass* ptr) { delete ptr; } private: myclass(/* args */) { ... } // Private CTOR and DTOR ~myclass() { ... } // } int main () { myclass m; // error: ctor and dtor are private myclass* mp = new myclass (..); // error: private ctor myclass* mp = myclass::create(..); // OK delete mp; // error: private dtor myclass::destroy(mp); // OK }
我知道你在问私人析构者。 这是我如何使用受保护的。 这个想法是你不想通过指向类的指针来删除主类,这个类增加了额外的function。
在下面的例子中,我不希望GuiWindow通过HandlerHolder指针被删除。
class Handler { public: virtual void onClose() = 0; protected: virtual ~Handler(); }; class HandlerHolder { public: void setHandler( Handler* ); Handler* getHandler() const; protected: ~HandlerHolder(){} private: Handler* handler_; }; class GuiWindow : public HandlerHolder { public: void finish() { getHandler()->onClose(); } virtual ~GuiWindow(){} };
dirkgently是错误的。 下面是一个在栈上创build私有c-tor和d-tor的对象的例子(我在这里使用了静态成员函数,但是也可以使用朋友函数或者朋友类来完成)。
#include <iostream> class PrivateCD { private: PrivateCD(int i) : _i(i) {}; ~PrivateCD(){}; int _i; public: static void TryMe(int i) { PrivateCD p(i); cout << "inside PrivateCD::TryMe, p._i = " << p._i << endl; }; }; int main() { PrivateCD::TryMe(8); };
此代码将产生输出:在PrivateCD :: TryMe中,p._i = 8
这可能是一种处理Windows中的问题的方法,其中每个模块都可以使用不同的堆,例如Debug堆。 如果这个问题没有得到正确处理,就会发生不好的 事情