后期构造静态成员变量

Constructing a static member variable late

我有一个 class 的静态成员,需要使用非默认构造函数来构造。代码是这样的:

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;
};

我这样做是因为在应用程序的生命周期内我需要 class 的一个实例,但是它需要使用只有在读取配置后才知道的参数来构造。 MyClass 的 superclass 将调用 MyClass 中的覆盖,这取决于了解这些配置项。

我一直在尝试寻找一种方法来声明一个静态 MyClass 成员,该成员最初只是一个占位符,以便以后可以构造它,但我的测试表明这似乎是不可能的。测试如下:

#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__);
}

所以我想我的问题是:如何声明但不构造静态成员? 我认为如果它没有默认构造函数,那将是可能的。

请告诉我我遗漏了一些简单的东西,并且有一种简单的方法可以做到这一点。

您在这里尝试做的是class真正的单例Class。 https://en.wikipedia.org/wiki/Singleton_pattern

您在第一个代码块中编写的 class 定义很好,应该可以工作。 class 静态对象将在第一次调用 initialise() 时初始化。

我认为问题出在你的测试代码上,你不应该在 main 中需要占位符变量。这将创建一个你的单例对象 class,你显然不想要它。

所以简而言之,为了纠正你的单例 class 你必须在编写单例时遵守以下规则 class,

  1. 私有的默认构造函数。
  2. 初始化函数是静态的。
  3. 你的class定义中的静态变量(实例)应该是指针或引用变量。

所以你的新测试 class 定义应该是这样的,

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__);
}