后期构造静态成员变量
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,
- 私有的默认构造函数。
- 初始化函数是静态的。
- 你的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__);
}
我有一个 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,
- 私有的默认构造函数。
- 初始化函数是静态的。
- 你的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__);
}