对象静态成员的初始化
静态成员有时会让我困惑。我已经知道如何初始化内建类型,例如int
沿的int myClass::statVar = 10;
线,您在.cpp文件放置的东西简单,但我有以下类似的东西:对象静态成员的初始化
class myClass
{
public:
// Some methods...
protected:
static RandomGenerator itsGenerator;
}
的基本思想是足够简单:myClass
需要访问它的一个成员函数的随机生成器。由于每个对象都相当大,我也只能拥有少数几个发生器实例。但是,RandomGenerator
类型需要“初始化”,可以这么说,通过调用RandomGenerator::Randomize()
,编译器不允许你这么做,因为它不是一个const rvalue(是吗?)。
那么我该如何做这项工作?
或者在这种情况下,我应该不使用静态变量,并以其他方式做?
您可以创建包装类,它将包含RandomGenerator
实例,并将在其构造函数中调用RandomGenerator::Randomize
。
把它放在一个私人字段中,公开一个静态存取器。在访问器中,如果成员尚未初始化,则对其进行初始化。
我正朝着这个方法努力。我认为这可能是更好的解决方案,虽然包装发电机也似乎是一个优雅的想法。 – 2010-07-20 10:16:05
这是坏的。外部类不应该知道发生器的存在。你只改变了它的方式。这是一种解决方法,但它不是解决方案。 – Gangnus 2011-12-19 08:27:15
在这些情况下,单身人士实际上是你的朋友,尽管他们还有其他缺点。
是的。我担心,在C++中它是唯一真正正确的方法。任何来自外太空的深层内部私人领域的设置都是不正确的。外围空间不应该知道内部发生器及其初始化。 – Gangnus 2011-12-19 07:57:15
@Gangus:查看我的其他评论。这不一定是真的。有时可以从外部提供策略。查看标准库 - 您可以将分配类型作为模板参数提供给基本上所有的容器类型,这是完全正确的。 – 2013-08-13 13:52:36
它只是一个需要使用RandomGenerator的函数吗?你可以这样做了这种方式:
INT MyClass的:: foo的(){ 静态 RandomGenerator itsGenerator = RandomGenerator ::随机化() ... }
这不起作用,因为Randomize不返回生成器。分隔线会导致发生器在您每次输入块时被随机化。 – 2010-07-20 10:17:24
如果RandomGenerator
是可复制,可使用用于初始化的辅助函数:
RandomGenerator init_rg() {
RandomGenerator rg;
rg.Randomize();
return rg;
}
RandomGenerator myClass::itsGenerator = init_rg();
初始化全局(静态)变量时要小心,因为不能保证排序。 – doron 2010-07-20 11:24:23
只写其返回引用到适当的随机RandomGenerator功能,把itsGenerator为参考发电机:
class myClass
{
public:
// Some methods...
protected:
// make this a reference to the real generator
static RandomGenerator& itsGenerator;
public:
static RandomGenerator& make_a_generator()
{
RandomGenerator *g=0;
g=new RandomGenerator();
g->Randomize();
return *g;
}
}
RandomGenerator& myClass::itsGenerator=myClass::make_a_generator();
为什么这么复杂,如果你只能返回一个堆栈分配的实例,让NRVO负责其余的部分或者使用一个函数本地'静态'实例? – 2010-07-20 10:50:12
即使使用NRVO,RandomGenerator也需要一个可访问的拷贝构造函数。我只是想避免不必要的要求。 – 2010-07-20 10:57:39
如果只有myClass
需要RandomGenerator
,则:
myClass::myClass()
{
itsGenerator.Randomize();
}
不要紧,如果你重新随机的随机数生成器为每个对象?我假设没有;-)
这是坏的。外部类不应该知道发生器的存在。你只改变了它的方式。这是一种解决方法,但它不是解决方案。 – Gangnus 2011-12-19 07:59:43
@Gangnus:不一定。封装一切都很好,但从外部提供策略没有任何问题,特别是如果您有可能将更多的责任归咎于现有的外部类别。 – 2013-08-13 13:51:48