C ++中的静态构造函数?我需要初始化私有静态对象


176

我想要一个带有私有静态数据成员(包含所有字符az的向量)的类。在Java或C#中,我可以创建一个“静态构造函数”,该构造函数将在创建该类的任何实例之前运行,并设置该类的静态数据成员。它只运行一次(因为变量是只读的,只需要设置一次),并且由于它是类的函数,因此可以访问其私有成员。我可以在构造函数中添加代码,以检查向量是否已初始化,如果尚未初始化,则将其初始化,但这会引入许多必要的检查,而且似乎不是解决问题的最佳方法。

我想到,由于变量将是只读的,因此它们只能是公共静态const,因此我可以在类外设置它们一次,但是再一次,这看起来像是一个丑陋的hack。

如果我不想在实例构造函数中初始化私有静态数据成员,是否可以在类中拥有私有静态数据成员?



1
@CiroSantilli新疆改造中心六四事件法轮功这个问题的重点是运行代码以初始化私有静态对象,而不是设置私有静态原始类型的常量值。解决方案是不同的。
Gordon Gustafson,

嗯,我想你是对的,退缩。
西罗Santilli郝海东冠状病六四事件法轮功

Answers:


180

要获得与静态构造函数等效的功能,您需要编写一个单独的普通类来保存静态数据,然后创建该普通类的静态实例。

class StaticStuff
{
     std::vector<char> letters_;

public:
     StaticStuff()
     {
         for (char c = 'a'; c <= 'z'; c++)
             letters_.push_back(c);
     }

     // provide some way to get at letters_
};

class Elsewhere
{
    static StaticStuff staticStuff; // constructor runs once, single instance

};

12
谢谢!尽管这样做很烦人。C#和Java的许多“错误”之一。
Gordon Gustafson,2009年

109
是。我总是向人们指出,如果C ++并没有犯所有这些“错误”,那么其他语言将不得不犯这些错误。C ++涵盖了如此多的领域,甚至犯了错误,对于遵循它的语言也非常有用。
夸克

11
只是一点点细微差别,随着构造函数的出现,没有人保证静态对象的构造函数执行时。另一个更安全的方法是类Elsewhere {StaticStuff&get_staticStuff(){static StaticStuff staticStuff; //构造函数只在有人需要时运行一次,返回staticStuff; }; 我想知道C#和Java中的静态构造函数是否可以提供与上面的代码相同的保证……
Oleg Zhylin,2009年

13
@Oleg:是的。标准保证:在输入main之前,将执行所有非局部变量的构造函数。它还保证了在编译单元内构造顺序的定义是明确的,并且与编译单元内的声明顺序相同。不幸的是,他们没有定义多个编译单元之间的顺序。
马丁·约克

13
实际上,这是friend很有意义的情况,以便类Elsewhere可以轻松访问StaticStuff的内部(我可以补充一点,而不会以任何危险的方式破坏封装)。
康拉德·鲁道夫
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.