【问题标题】:What is the use of having destructor as private?将析构函数设为私有有什么用?
【发布时间】:2010-10-12 12:28:21
【问题描述】:

将析构函数设为私有有什么用?

【问题讨论】:

    标签: c++ private destructor


    【解决方案1】:

    基本上,只要您希望某个其他类负责您的类对象的生命周期,或者您有理由阻止对象的销毁,您都可以将析构函数设为私有。

    例如,如果您正在做某种引用计数的事情,您可以让对象(或已“加为好友”的管理器)负责计算对自身的引用次数,并在数量达到时将其删除零。当仍有对它的引用时,私有 dtor 会阻止其他任何人删除它。

    另外一个例子,如果你有一个对象有一个管理器(或它本身),它可能会根据程序中的其他条件(例如数据库连接打开或文件正在打开)销毁或拒绝销毁它,该怎么办?书面。您可以在类或管理器中有一个“request_delete”方法来检查该条件,它将删除或拒绝,并返回一个状态,告诉您它做了什么。这比仅仅调用“删除”要灵活得多。

    【讨论】:

      【解决方案2】:

      当您不希望用户访问析构函数时,即您希望仅通过其他方式销毁对象。

      http://blogs.msdn.com/larryosterman/archive/2005/07/01/434684.aspx 给出了一个示例,其中对象被引用计数,并且只有当计数变为零时才应由对象本身销毁。

      【讨论】:

        【解决方案3】:

        类只能自行删除。如果您正在创建一些引用计数对象的尝试,这很有用。那么只有release方法才能删除对象,可能会帮助你避免错误。

        【讨论】:

          【解决方案4】:

          这样的对象永远不能在堆栈上创建。总是在堆上。删除必须通过朋友或会员完成。一个产品可能使用一个单一的对象层次结构和一个自定义的内存管理器——这样的场景可能会使用一个私有的 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;
          }
          

          【讨论】:

          • 更正:这样的对象可以在堆栈上创建(但只能在朋友或自己的范围内)。
          • 此外,它不能在托管实现中包含静态或全局对象(即具有“静态存储持续时间”)(因为将在程序退出时调用析构函数)。
          • 更正2:可以使用placement new在堆栈上创建这样的对象。
          • 与栈无关。在堆上创建和销毁它的相同方法也可以在堆栈上使用。
          【解决方案5】:

          这可能是解决 Windows 中每个模块可以使用不同堆的问题的一种方法,例如 Debug 堆。如果没有正确处理该问题,badthings 可能会发生。

          【讨论】:

            【解决方案6】:

            我知道你问的是私有析构函数。这是我如何使用受保护的。这个想法是您不想通过指向为主类添加额外功能的类的指针来删除主类。
            在下面的示例中,我不希望通过 HandlerHolder 指针删除 GuiWindow。

            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(){}
            };
            

            【讨论】:

              【解决方案7】:

              COM 使用此策略删除实例。 COM 将析构函数设为私有,并提供删除实例的接口。

              下面是 Release 方法的示例。

              int MyRefCountedObject::Release() 
              {
               _refCount--;
               if ( 0 == _refCount ) 
               {
                  delete this;
                  return 0;
               }
               return _refCount;
              }
              

              ATL COM 对象是这种模式的主要示例。

              【讨论】:

                【解决方案8】:

                很明显是错误的。这是在堆栈上创建的具有私有 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

                【讨论】:

                • 我敢肯定,这意味着使用您的类的代码无法实例化堆栈上的类。当然,您仍然可以在 within 类方法的堆栈上实例化该类,因为在这种情况下,您可以访问私有成员。
                【解决方案9】:

                添加到这里已经存在的答案;私有构造函数和析构函数在实现factory 时非常有用,其中创建的对象需要在堆上分配。通常,对象将由静态成员或朋友创建/删除。典型用法示例:

                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
                }
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2011-01-21
                  • 2019-10-16
                  • 2013-06-24
                  • 1970-01-01
                  相关资源
                  最近更新 更多