3

我测试了一种在 C++ 中声明单例类的模式,该模式使默认析构函数为“私有”,但该模式没有通过任何成员调用使用此析构函数。

我使用 gnu g++ 编译器在 Ubuntu QQ 上测试了这段代码——在程序终止时调用了析构函数,尽管被指定为“私有”。

谁/什么/如何调用这个析构函数,因为它被指定为私有的?

注意:我来自 Delphi/Object Pascal 世界,ObjectPascal 不支持静态类声明——尽管有几种方法可以创建单例。以我的经验, 'private'('strict private'...) 是PRIVATE。我看到在 C++ 中情况并非如此。

解释?

4

4 回答 4

4

该对象通常由static称为类似的成员函数实例化getInstance,然后为您提供对该对象的引用。因为它是一个成员函数,所以它可以访问构造函数。

经典例子:

class S
{
    public:
        // This is a member function so can access the constructor of S
        static S& getInstance()
        {
            static S    instance;
            return instance;
        }
    private:
        S() {};
        S(S const&);
        void operator=(S const&);
};
于 2013-05-06T17:56:28.213 回答
1

(OP编辑后编辑)

将析构函数设为私有可防止显式调用它。

如果析构函数是公开的,这将是合法的:

 MyClass.getInstance().~MyClass();

静态存储对象的析构函数作为从 main() 返回或调用 exit() 的结果被调用。

于 2013-05-06T17:55:39.420 回答
1

典型的单例类有一个静态成员函数,它返回一个指向单例对象的指针。例如:

Singleton *Singleton::instance();

其中instance()是静态成员函数。静态成员函数可以调用私有构造函数。

于 2013-05-06T17:57:07.817 回答
1

它们是私有的,因为您不希望允许外部的任何代码构造或破坏该对象。单例通常有一个静态实例,通过工厂方法初始化和删除。

tempalte <class T>
class Singleton
{
public:
    static T* GetInstance()
    {
        if(!m_sInstance)
        {
            m_sInstance = new T();
        }

        return m_sInstance;
    }

    static void DestroyInstance()
    {
        delete m_sInstance;
        m_sInstance = 0;
    }
private:
    static T* m_sInstance;    
};

class Foo : public Singleton<Foo>
{
friend class Singleton<Foo>;
private:
    Foo();
    ~Foo();
};

所以你可以调用Foo::GetInstance()andFoo::DestroyInstance()来访问和删除单例对象。

于 2013-05-06T18:18:19.837 回答