2

I like to experiment around as I learn more about coding. I have a program that would only require a single instance of a struct for the life of it's runtime and was wondering if it's possible to create a singleton struct. I see lot's of information on making a singleton class on the internet but nothing on making a singleton struct. Can this be done? If so, how?

Thanks in advance. Oh, and I work in C++ btw.

Jake
  • 189
  • 2
  • 9
  • 6
    Remember that in C++ a `class` and `struct` are the same. The only difference is that a `struct` defaults to members being `public`. – Some programmer dude Mar 03 '13 at 15:39
  • Does that mean you can put methods in a struct? (if they are the 'same'). And, if so, then I can do things like operator overloading in a struct? – Jake Mar 03 '13 at 15:48
  • Note that static initialisation is not thread safe before C++11 so you would need a mutex to prevent a race condition if you call the ``singleton::get_instance()`` from multiple threads. – Roman Kutlak Mar 03 '13 at 16:22
  • 1
    @JoachimPileborg and inheritance defaults to `public` too. –  Mar 03 '13 at 19:02

5 Answers5

10

A class and a struct are pretty much the same thing, except for some minor details (such as default access level of their members). Thus, for example:

struct singleton
{
    static singleton& get_instance()
    {
        static singleton instance;
        return instance;
    }

    // The copy constructor is deleted, to prevent client code from creating new
    // instances of this class by copying the instance returned by get_instance()
    singleton(singleton const&) = delete;

    // The move constructor is deleted, to prevent client code from moving from
    // the object returned by get_instance(), which could result in other clients
    // retrieving a reference to an object with unspecified state.
    singleton(singleton&&) = delete;

private:

    // Default-constructor is private, to prevent client code from creating new
    // instances of this class. The only instance shall be retrieved through the
    // get_instance() function.
    singleton() { }

};

int main()
{
    singleton& s = singleton::get_instance();
}
Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
  • 2
    @Spook: Correct. I forgot to add the `static` keyword. I did that in my mind only. Edited, thank you. – Andy Prowl Mar 03 '13 at 15:42
  • You did not hid the copy-ctor and = operator. One may create a instance by copying existing instance of singleton. Effectively you have to implement the singleton as you would do it if `singleton` was a class. – Spook Mar 03 '13 at 15:48
  • @Spook: Actually, I guess the assignment operator does not need to be protected, but the move constructor does. I will edit again – Andy Prowl Mar 03 '13 at 15:54
  • I have actually preferred to `delete` copy construction and assignment. I cannot see what use keeping private versions would have, but I haven't really thought it through very much. – juanchopanza Mar 03 '13 at 16:01
  • 1
    Now you are getting too excited with the deletes :-D Aside from the syntax error here ``singleton() { } = delete;`` you need at least one ctor so that you can construct the object. – Roman Kutlak Mar 03 '13 at 16:19
  • @RomanKutlak: Aand you are correct as well. Edited. Thank you. – Andy Prowl Mar 03 '13 at 16:22
5

Struct and class are in C++ almost the same (the only difference is default visibility of members).

Note, that if you want to make a singleton, you have to prevent struct/class users from instantiating, so hiding ctor and copy-ctor is inevitable.

struct Singleton
{
private:
    static Singleton * instance;

    Singleton()
    {
    }

    Singleton(const Singleton & source)
    {
        // Disabling copy-ctor
    }

    Singleton(Singleton && source)
    {
        // Disabling move-ctor
    }

public:
    static Singleton * GetInstance()
    {
        if (instance == nullptr)
            instance = new Singleton();

        return instance;
    }
}
Spook
  • 25,318
  • 18
  • 90
  • 167
  • I had no idea you could put methods in structs like that. Thanks. I'm upvoting this because a simple code example was one of the thngs I really wanted (not the only thing, but a very important thing). – Jake Mar 03 '13 at 16:21
  • Turns out this is Java, not C++. With a little tweaking it can be made to work thoug - just that it won't compile wtih g++ as it is shown. – Jake Mar 03 '13 at 19:55
2

Conceptually, a struct and a class are the same in C++, so a making singleton struct is the same as making a singleton class.

The only difference between class and struct are the default access specifiers and base class inheritance: private for class and public for struct. For example,

class Foo : public Bar 
{ 
 public: 
  int a;
};

is the same as

struct Foo : Bar
{
 int a;
};

So, there is no fundamental difference when it comes to singletons. Just make sure to read about why singletons are considered bad.

Here's a simple implementation:

struct singleton
{
  static singleton& instance()
  {
    static singleton instance_;
    return instance_;
  }
  singleton(const singleton&)=delete;            // no copy
  singleton& operator=(const singleton&)=delete; // no assignment

 private:
  singleton() { .... } // constructor(s)
};
Community
  • 1
  • 1
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
1

First off, struct and class only refer to the default access of members. You can do everything with a struct that you can do with a class. Now if you were referring to POD structs, things get more complicated. You can't defined a custom constructor, so there's no way to enforce only a single object creation. However, there's nothing stopping you from simply only instantiating it once.

Antimony
  • 37,781
  • 10
  • 100
  • 107
  • Thank you. Very succinct and comprehansive. Reading this makes it all pretty clear to me. – Jake Mar 03 '13 at 16:23
  • Definition of POD: http://stackoverflow.com/questions/146452/what-are-pod-types-in-c – Jake Mar 03 '13 at 16:25
  • Now, wait a minute, does this mean I can't include attributes in my singleton struct design? That's kind of the whole point. The one instance of the struct in the program is only every used as a temporary transition place for data (a record with 4 fields). The following is the code I have for my struct but was hoping to 'add' code to it, to make it a singleton: struct Record { //the record - temporary - reuse - singleton? int DeptNum; char Name[MAXNAME]; int Age; int EmplID; // key field }; – Jake Mar 03 '13 at 16:32
0

class and struct is almost a synonyms in C++. For singleton use case they are complete synonyms.

hate-engine
  • 2,300
  • 18
  • 26