3

I tested a pattern for declaring a singleton class in C++ that makes the default destructor 'private', but the pattern makes no use of this destructor through any member call.

I tested this code on Ubuntu QQ using the gnu g++ compliler - the destructor was called on program termination, although designated 'private'.

Who/What/How is this destructor called, since it's designated private?

Note: I am coming from the Delphi/Object Pascal world, and there is no static class declaration supported by ObjectPascal - although there are several ways to create a singleton. In my experience, 'private'('strict private'...) is PRIVATE. I see that in C++ it is not quite that way.

Explanation?

Ken White
  • 123,280
  • 14
  • 225
  • 444
Vector
  • 10,879
  • 12
  • 61
  • 101
  • possible duplicate of [How are the private destructors of static objects called?](http://stackoverflow.com/questions/11524131/how-are-the-private-destructors-of-static-objects-called) – Andy Thomas May 06 '13 at 21:08

4 Answers4

4

The object is typically instantiated by a static member function called something like getInstance, which then gives you a reference to the object. Because it's a member function, it has access to the constructor.

The classic example:

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&);
};
Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
1

(Edited after OP edit)

Making the destructor private prevents it from being called explicitly.

If the destructor were public, this would be legal:

 MyClass.getInstance().~MyClass();

The destructors of static storage objects are called as a result of returning from main() or calling exit().

Andy Thomas
  • 84,978
  • 11
  • 107
  • 151
  • @Mikey - The new question is answered above. – Andy Thomas May 06 '13 at 19:16
  • See new question title and edit... :-) I guess I wasn't making my question clear enough – Vector May 06 '13 at 20:36
  • You asked if it should be public. The second question is addressed by http://stackoverflow.com/questions/11524131/how-are-the-private-destructors-of-static-objects-called . – Andy Thomas May 06 '13 at 21:08
  • OK - I see over there what someone quoted from the standard - according to that, the answer is YES, the mechanism that cleans up statics is not restricted by access modifiers. I can easily test this as well... let's see what else comes up here - I have no problem giving you the credit. – Vector May 06 '13 at 21:46
1

Typical singleton classes have a static member function that returns a pointer to the singleton object. For example:

Singleton *Singleton::instance();

where instance() is a static member function. The static member function can call private constructors.

Marc Claesen
  • 16,778
  • 6
  • 27
  • 62
  • Obvious - dumb question on my part re constructors - see edit. – Vector May 06 '13 at 19:02
  • If I am not mistaken, the destructor of static objects is called when the program terminates. – Marc Claesen May 06 '13 at 19:06
  • So I would think - but what's calling it? If destructor is private, it can't be called by anything external. And if the default destructor will get called anyhow, what's the point of declaring it private? And what if you have cleanup code in your destructor? I think something is not right with this design. – Vector May 06 '13 at 19:13
  • I have never used this particular idiom myself (singletons with private destructors), so I can't vouch for its effectiveness. The point of declaring the destructor private is simple though: this ensures no user can ever destroy the singleton object. If the destructor is not private, anyone could destroy the singleton through `delete Singleton::instance();` – Marc Claesen May 06 '13 at 19:19
  • 'anyone could destroy the singleton' - understood. See new question title and edit... :-) I guess I wasn't making my question clear enough. – Vector May 06 '13 at 20:35
1

They are private because you don't want to allow construction or destruction of that object by any code outside. Singletons generally have a static instance that is initialized and deleted via factory methods.

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

So you can call Foo::GetInstance() and Foo::DestroyInstance() to access and delete the singleton object.

SNce
  • 2,453
  • 1
  • 16
  • 14