0

I'm implementing Singleton the way described in the first answer here. The getInstance() method returns a reference but what I'm not sure about is how I should create my new instance and check if it already exists before creating it and returning it.

class Song {

private:
    Song song;
    Song();
    Song(Song const&); // don't implement
    void operator = (Song const&); //don't implement

public:
    static Song &getInstance();
}

So what should my getInstance(); implementation look like? I want to return the song member object if it already exists and otherwise create it and than return it. I know there's a n implementation in the link I added but I'm not sure it does what I want and I don't understand it very well.

Also, could someone explain what these two lines are for and why the = operator is being overwritten?

    Song(Song const&); // don't implement
    void operator = (Song const&); //don't implement
Community
  • 1
  • 1
  • 2
    isn't [first answer there](http://stackoverflow.com/questions/1008019/c-singleton-design-pattern/1008289#1008289) already provides an implementation for getInstance and answers why copy constructor and assignment are declared private? – yuri kilochek Jul 26 '12 at 13:52

3 Answers3

1

The implementation is in the answer you quote:

static S& getInstance()
{
    static S    instance; // Guaranteed to be destroyed.
                          // Instantiated on first use.
    return instance;
}

The instance is static, so it gets instantiated at the first call of the getInstance() function.

See this related SO question for more information.

A note on the second question. The first is the copy constructor:

Song(Song const&);

It is needed if you want to initialize an object to take the value of another one:

Song a;
Song b = a; // calls copy constructor

The second is an assignment operator:

void operator=(const Song&);

needed for assigning a value to an already existing instance:

Song a;
Song b;
b = a; // calls assignment operator.

Note that the standard return value for an assignment operator is a reference:

Song& operator=(const Song&);
Community
  • 1
  • 1
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • But doesn't that mean that my instance will be recreated every time? –  Jul 26 '12 at 13:59
  • 1
    @Sled No, the `static` keyword indicates that `instance` is the only one created for each invocation. You can play with an `static int` variable in a function you call several times to see how it works. – JohnMcG Jul 26 '12 at 14:01
  • So that also means I don't need to add the object as a member because I have a static function with a static object inside it? –  Jul 26 '12 at 14:06
  • 1
    @Sled exactly, the object lives from first call to program termination, so it cannot be a plain data member. But please read Mike Seymour's answer for explanations of pitfalls of this method. – juanchopanza Jul 26 '12 at 14:14
1

So what should my getInstance(); implementation look like? I want to return the song member object if it already exists and otherwise create it and than return it.

That's exactly what the code you link do does. To quote that answer:

static S& getInstance()
{
    static S    instance; // Guaranteed to be destroyed.
                          // Instantiated on first use.
    return instance;
}

As the comment says, it is instantiated on first use; that's how static variables at function scope work.

The deathtrap associated with this particular attempt to implement the Singleton anti-pattern is that it's possible to access it after it's destroyed, for example from the destructor of another static object.

Also, could someone explain what these two lines are for and why the = operator is being overwritten?

These are to prevent copying the object. Copying can be done with either a copy constructor (creating a new object) or a copy-assignment operator (overwriting an existing object); if these are declared private and not implemented, then the instance can't be copied. In C++11, this can be made more explicit by deleting them:

Song(Song const&) = delete;
void operator = (Song const&) = delete;
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • Can you tell me one more thing? How exactly shoudl I call the `getInstance` method? I tried `song = Song::getInstance();` but that doesn't work.. –  Jul 26 '12 at 14:21
  • 1
    @Sled: That's because you're trying to copy it, which isn't allowed. Instead, you can use it directly, e.g. `Song::getInstance().sing();`, or use it to initialise a reference, e.g. `Song & song = Song::getInstance();` – Mike Seymour Jul 26 '12 at 14:27
0

To answer the second question, those two lines declare the copy constructor and assignment operator as private, so that they can't be called. Without those two lines, the compiler would generate default implementations of these, and clients could create copies, defeating the purpose of the Singleton pattern.

JohnMcG
  • 8,709
  • 6
  • 42
  • 49