2

I have read some of the wikis in StackOverflow, and I've written the following header file for my Randomizer class:

class Randomizer
{
    public:
        static Randomizer& instance(void);
        int nextInt(int);
        int nextInt(int, int);
        int die(int);
        double nextDouble(void);
        char randomChar(const std::string&);
    private:
        Randomizer(void) {};
        /* No implementation of the following methods */
        Randomizer(Randomizer const&);
        void operator= (Randomizer const&);
};

I have also implemented some of the methods inside of the class, like nextInt and such.

I am unsure about how to make an instance of this Singleton class, i.e. how to write a test drive in main()?

I tried:

int main()
{
     Randomizer r;
     r = Randomizer::instance();
}

Compiler says a few errors:

In file included from Randomizer.cpp:11:0:
Randomizer.h: In function ‘int main(int, char**)’:
Randomizer.h:22:9: error: ‘Randomizer::Randomizer()’ is private
         Randomizer(void) {};
         ^
Randomizer.cpp:56:16: error: within this context
     Randomizer r;
                ^
In file included from Randomizer.cpp:11:0:
Randomizer.h:25:14: error: ‘void Randomizer::operator=(const Randomizer&)’ is private
         void operator= (Randomizer const&);
              ^
Randomizer.cpp:57:7: error: within this context
     r = Randomizer::instance();
       ^

Thanks for help.

hlx98007
  • 241
  • 5
  • 15
  • 1
    private unimplemented methods are a bit outdated -- it's clearer to use `method_signature() = delete;` since C++11. Anyway, the reason for the error is that you're (attempting to) make a copy of the instance, which you've forbidden with the private assignment operator. – Cameron Oct 08 '14 at 16:11
  • @Cameron, thanks for the quick reply. How to use the method_signature function instead of using the private unimplemented methods? – hlx98007 Oct 08 '14 at 16:16
  • @hlx98007: `method_signature()` was a placeholder for the method you want to forbid from the class. – Jack Oct 08 '14 at 16:17
  • @hlx98007: Simply add `= delete` to the end of each unwanted method's declaration (after the closing parenthesis of the argument list and before the semicolon). You may also have to tweak your compiler's flags to compile under C++11 (e.g. with g++ add `-std=c++11` on the command line). – Cameron Oct 08 '14 at 16:18
  • @Cameron, like that `Randomizer() = delete` or `void operator= = delete`? (In the header file under class declaration) – hlx98007 Oct 08 '14 at 16:19
  • @hlx98007: `Randomizer() = delete;` and `Randomizer& operator=(Randomizer const&) = delete;`. See: http://www.stroustrup.com/C++11FAQ.html#default – Cameron Oct 08 '14 at 16:19
  • "I have read some of the wikis in StackOverflow" - did you read http://stackoverflow.com/questions/137975? – Mike Seymour Oct 08 '14 at 16:22

2 Answers2

5

This code tries to copy the Randomizer instance. If you don't want to directly use the result of the instance() call, you should take the returned reference:

Randomizer &r = Randomizer::instance();
Denys Bulant
  • 316
  • 4
  • 10
5

You are saying that you want a singleton but:

Randomizer r; 

This constructs a new instance of Randomizer by trying to call the default empty constructor. So you are not using it as a singleton, in addition you declared the constructor private.

r = Randomizer::instance();

Here you are trying to copy assign a singleton to another, which you explicitly declared private.

Maybe you meant to use:

Randomizer &r = Randomizer::instance()

Probably it's also better to have a const Randomizer& instance() method instead that a mutable reference if the randomizer itself doesn't have a visibile state.

Jack
  • 131,802
  • 30
  • 241
  • 343