当构造函数是私有时使用公共析构函数

San*_*alp 7 c++ destructor public

我已经看到了代码,其中构造函数已被声明为私有,而析构函数是公共的.这种声明有什么用?析构函数是否需要公开,以便在继承期间调用是可能的,还是代码中的错误?

这个问题在信息上似乎有点短,但我真正想知道的是,当构造函数需要私有时遵守C++规则是否有公共析构函数?

mat*_*dev 6

简答

将构造函数创建为私有,但将析构函数创建为public,具有许多实际用途.

您可以使用此范例:

答案很长

上面我暗示你可以使用私有构造函数和析构函数来实现几种设计模式.嗯,这是怎么...

参考计数

在对象中使用私有析构函数会使自己适用于引用计数系统.这使开发人员可以更好地控制对象的生命周期.

class MyReferenceObject
{
public:
    static MyReferenceObject* Create()
    {
        return new MyReferenceObject();
    }

    void retain()
    {
        m_ref_count++;
    }

    void release()
    {
        m_ref_count--;
        if (m_ref_count <= 0)
        {
            // Perform any resource/sub object cleanup.
            // Delete myself.
            delete this; // Dangerous example but demonstrates the principle.
        }
    }
private:

    int m_ref_count;

    MyReferenceObject()
    {
        m_ref_count = 1;
    }

    ~MyReferenceObject() { }

}

int main()
{
    new MyReferenceObject(); // Illegal.
    MyReferenceObject object; // Illegal, cannot be made on stack as destructor is private.

    MyReferenceObject* object = MyReferenceObject::Create(); // Creates a new instance of 'MyReferenceObject' with reference count.
    object->retain(); // Reference count of 2.
    object->release(); // Reference count of 1.
    object->release(); // Reference count of 0, object deletes itself from the heap.
}
Run Code Online (Sandbox Code Playgroud)

这演示了对象如何管理自身并防止开发人员破坏内存系统.请注意,这是一个危险的示例,因为MyReferenceObject删除自身,请参阅此处以获取执行此操作时要考虑的事项列表.

独生子

单例类中私有构造函数和析构函数的一个主要优点是强制用户仅以代码设计的方式使用它.无法创建流氓单例对象(因为它在编译时强制执行),并且用户无法删除单例实例(再次,在编译时强制执行).

例如:

class MySingleton
{
public:
     MySingleton* Instance()
     {
        static MySingleton* instance = NULL;
        if (!instance)
        {
            instance = new MySingleton();
        }

        return instance;
     }
private:
    MySingleton() { }
    ~MySingleton() { } 
}

int main()
{
     new MySingleton(); // Illegal
     delete MySingleton::Instance(); // Illegal.
}
Run Code Online (Sandbox Code Playgroud)

看看代码几乎不可能被滥用.正确使用它MySingleton是在编译时强制执行,从而确保开发人员必须MySingleton按预期使用.

在工厂设计模式中使用私有构造函数是强制仅使用工厂来创建对象的重要机制.

例如:

class MyFactoryObject
{
public:

protected:
    friend class MyFactory; // Allows the object factory to create instances of MyFactoryObject

    MyFactoryObject() {} // Can only be created by itself or a friend class (MyFactory).
}

class MyFactory
{
public:
    static MyFactoryObject* MakeObject()
    {

        // You can perform any MyFactoryObject specific initialisation here and it will carry through to wherever the factory method is invoked.
        return new MyFactoryObject();
    }
}

int main()
{
    new MyFactoryObject(); // Illegal.
    MyFactory::MakeObject(); // Legal, enforces the developer to make MyFactoryObject only through MyFactory.
}
Run Code Online (Sandbox Code Playgroud)

这很有用,因为它隐藏MyFactoryObject了开发人员的创建.您可以使用工厂方法执行任何初始化MyFactoryObject(例如:设置GUID,注册到DB)以及使用工厂方法的任何地方,也将执行初始化代码.

摘要

这只是一些如何使用私有构造函数和析构函数来强制正确使用API​​的示例.如果你想变得棘手,你也可以结合所有这些设计模式;)


cpp*_*cpp 1

如果您想防止创建多个类的实例,则可以将构造函数设置为私有。这样您就可以控制实例的创建而不是它们的破坏。因此,析构函数可以是公共的。