0

There is a need in my project for a registry that would hold some states and that could be easily accesible from anywhere in the code. Singleton is something we already use in a classic implementation static X& X::instance() { static X instance; return instance; } But this causes issues in UT. I came up with such a idea

smartSingletonWrapper.h

class smartSingletonWrapper
{
public:
    smartSingletonWrapper(arg_for_Actual_Singleton)
    {
        instance.reset(make_shared<Actual_Singleton>(arg_for_Actual_Singleton));
    }

    ~smartSingletonWrapper()
    {
        assert(instance.count() == 1, "In case you want sanity checks");
        instace.reset();
    }

    static shared_ptr<Actual_Singleton> getInstance() //or weak_ptr
    {
        return instance;
    }    
private:
    static shared_ptr<Actual_Singleton> instance;

    class Actual_Singleton //or implement elsewhere with private constructor and wrapper as friend class
    {
        //stuff..
    }
}

smartSingletonWrapper.cpp

shared_ptr<Actual_Singleton> smartSingletonWrapper::instance;

Now usage of this would be:

int main(argc, argv)
{
    smartSingletonWrapper raii_singleton_holder;
    invoke_milions_lines_of_code();
    return 0;
}

in UT well same story just create this object anywhere where it will run out of scope after 1 test is over. Example basing on gtest:

class ut_class_using_actual_singleton : public testing::Test
{
public:
    class_using_actual_singleton system_under_test;
    smartSingletonWrapper
};

TEST_F(ut_class_using_actual_singleton, some_test)
{
     test_stuff();
}

This is simple yet working version. You can enhance it by making this class a template accepting just any kind of singleton class inside it. You can add sanity checks (for example checking if there is only one instance of this smartSingleton).

Does anyone see any issues with this idea? Have anyone heard of similar idea? I don't believe that I actually invented something no-one has ever described before.

Marcin K.
  • 683
  • 1
  • 9
  • 20
  • 1
    If you have a public constructor you do not have a singleton. – NathanOliver Nov 18 '16 at 15:19
  • 1
    There's a *big* flaw in your reasoning: You have the constructor being `public`, that means anyone could create an instance of your class. You're also forgetting that [templates only can be implemented in header files](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file). – Some programmer dude Nov 18 '16 at 15:20
  • Ok i edited the code to make it clearer that the big class is just a wrapper for a true singleton ( true singleton = actual_singleton previously named X) – Marcin K. Nov 18 '16 at 15:27
  • 1
    When I do singletons, I like to have something of the form: `class X {}` + `class SingletonX { public: static X& getX(); }` meaning should one ever want the same functionality in a not-singleton, you can get it trivially; and the singleton class does no more than deal with the singleton instance. – UKMonkey Nov 18 '16 at 15:33
  • Yeah this is just my idea for it - a RAII wrapper to 'deal with singleton instance'. My implementation will stick with regular singleton with private construction. But I understand that sometimes you may want to trust your fellow team members more in order to get some flexibility. – Marcin K. Nov 18 '16 at 15:39
  • "you may want to trust your fellow team members": nope, never – UKMonkey Nov 18 '16 at 15:40
  • Well I believe this is perfectly what you suggested in your previous comment by saying "meaning should one ever want the same functionality in a not-singleton, you get it trivially(...)" – Marcin K. Nov 18 '16 at 15:52

0 Answers0