0

I've got a static member of a class that needs to be constructed using the non-default constructor. The code is like this:

class MyClass
{
public:
   static void initialise(int arg1, int arg2)
   {
      static MyClass instance(arg1, arg2);
      _instance = instance;
   }

   static MyClass& instance()
   {
      return _instance;
   }

   /* Other non-static functions used with the return of instance()... */

private:
   MyClass(int arg1, int arg2)
      : _arg1(arg1), _arg2(arg2) {}

   static MyClass& _instance;
   int _arg1, _arg2;
};

I do this because I need one instance of the class for the lifetime of the application, however it needs to be constructed with arguments that are only known after configuration has been read. The superclass of MyClass will invoke an override in MyClass which depends on knowing these configuration items.

I've been trying to find a way to declare a static MyClass member which starts as just a placeholder so it can be constructed later, but my tests make it seem that this isn't possible. The test is below:

#include <cstdio>

class CNoDefCtor
{
public:
    CNoDefCtor(int arg1)
        : _arg1(arg1)
    {
        printf("%s\n", __func__);
    }

    virtual ~CNoDefCtor()
    {
        printf("%s\n", __func__);
    }

    static void Initialise(int arg1)
    {
        printf("%s\n", __func__);
        CNoDefCtor _instance(arg1); /* Actually construct here?!? */
    }

    static CNoDefCtor& instance()
    {
        return _instance;
    }

    int Arg1()
    {
        return _arg1;
    }

private:
    int _arg1;
    static CNoDefCtor _instance;
};

int main()
{
    printf("%s\n", __func__);

    CNoDefCtor ndc; /* Placeholder? */
    ndc.Initialise(1);
    printf("%d\n", ndc.Instance().Arg1());

    printf("%s\n", __func__);
}

So I guess my question is: how do you declare but not construct a static member? I thought that if it didn't have a default constructor it would be possible.

Please tell me I'm missing something simple and that there is an easy way to do this.

3
  • Why not keep the static member as a pointer (or a shared_ptr)? The default value will be NULL, and create() would call new... Commented Nov 30, 2015 at 16:32
  • Since you have an instance() function anyway, it would be much simpler to make the actual object a static variable of the instance() function, rather than a static member of the class. Commented Nov 30, 2015 at 16:44
  • Depending on other details of your requirements, I expect you would want the only constructor to be a private default constructor that does nothing, then handle initialization with a non constructor function. Commented Nov 30, 2015 at 16:49

1 Answer 1

1

What you are trying to do here is a classical Singleton Class. https://en.wikipedia.org/wiki/Singleton_pattern

The class definition that you wrote in the first code block is fine and should work. The class static object will be initialized on the first call to initialise().

I think the problem is with your test code, you should not need the place holder variable in main. This would create an object of your singleton class, which you obviously you don't want.

So in short to correct your singleton class you have to obey following rules whenever writing a singleton class,

  1. Default Constructor in private.
  2. The initialization function is static.
  3. The static variable (instance) in your class definition should be a pointer or a reference variable.

So your new test class definition should look like,

class CNoDefCtor : public CAnnoyingClass
{
private:
    CNoDefCtor(int arg1)
        : _arg1(arg1)
    {
        printf("%s\n", __func__);
    }

public:
    virtual ~CNoDefCtor()
    {
        printf("%s\n", __func__);
    }

    static void Initialise(int arg1)
    {
        printf("%s\n", __func__);
        _instance = new CNoDefCtor(arg1);
    }

    static CNoDefCtor& instance()
    {
        return *_instance;
    }

    int Arg1()
    {
        return _arg1;
    }

private:
    int _arg1;
    static CNoDefCtor *_instance;
};

int main()
{
    printf("%s\n", __func__);

    CNoDefCtor::Initialise(1);
    printf("%d\n", CNoDefCtor::Instance().Arg1());

    printf("%s\n", __func__);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.