C++ C+中的静态类+;

C++ C+中的静态类+;,c++,class,static,C++,Class,Static,在我声明的标题中 #ifndef SOUND_CORE #define SOUND_CORE static SoundEngine soundEngine; ... 但是SoundEngine的构造函数被多次调用,当它被声明为全局静态时,怎么可能呢 我称之为 #include "SoundCore.h" 并直接使用它 soundEngine.foo() 谢谢您将为包含标题的每个翻译单元创建标题文件中声明的静态变量副本。 永远不要在头文件中声明静态变量 您可以使用一个对象。如果您在多个文

在我声明的标题中

#ifndef SOUND_CORE
#define SOUND_CORE

static SoundEngine soundEngine;

...
但是SoundEngine的构造函数被多次调用,当它被声明为全局静态时,怎么可能呢

我称之为

#include "SoundCore.h"
并直接使用它

soundEngine.foo()

谢谢您

将为包含标题的每个翻译单元创建标题文件中声明的静态变量副本。
永远不要在头文件中声明静态变量


您可以使用一个对象。

如果您在多个文件中包含此头文件,您的类将在每次包含时被实例化。我认为您最好看看Singleton模式,只获得一个实例,即一个构造函数调用。

与许多其他保留字一样,static是一个修饰符,根据上下文具有不同的含义

在本例中,您正在创建SoundEngine类的对象,该对象在此模块中是私有的。这意味着它在其他模块中不可见


但是,您将这一行放在标题中,因此它是各个模块中的私有对象。我想这就是构造函数被多次调用的原因。

正如其他人在回答中提到的那样,
头文件中的static
变量包含在包含头文件的每个文件中。如果您仍希望保持它的
静态
,并避免多次实例化,则将其包装在
结构中

//SoundCore.h
struct Wrap {
  static SoundEngine soundEngine;
};
现在在一个
.cpp
文件中定义此变量

//SoundCore.cpp
SoundEngine Wrap::soundEngine;
把它当作

Wrap::soundEngine.foo();

我会使用
extern
而不是static。这就是
extern
的作用

在标题中:

extern SoundEngine soundEngine;
在附带的源文件中:

SoundEngine soundEngine;
这将为实例创建一个翻译单元,包含头将允许您在代码中的任何地方使用它

// A.cpp
#include <iostream>
// other includes here
...
extern int hours; // this is declared globally in B.cpp

int foo()
{
hours = 1;
}


// B.cpp
#include <iostream>
// other includes here
...
int hours; // here we declare the object WITHOUT extern
extern void foo(); // extern is optional on this line

int main()
{
foo();
}
//A.cpp
#包括
//其他包括在这里
...
外部整数小时;//这是在B.cpp中全局声明的
int foo()
{
小时=1;
}
//B.cpp
#包括
//其他包括在这里
...
整小时;//在这里,我们不使用extern声明对象
extern void foo();//在这一行中,extern是可选的
int main()
{
foo();
}

是,静态是每个翻译单位。补救方法是单例或类似的。愚蠢的我在想:你能做“extern SoundEngine SoundEngine”,然后在一个编译单元中实现为静态的(也就是说,没有extern关键字)?@Mario The Spoon:是的,你能做到,它是完全有效的,并且可以工作,但是作为个人选择,我真的不喜欢以这种方式使用extern。单例和
extern
对象都有问题(从设计角度和在C++中的工作方式来看)。我的首选方法是实例化函数中的对象(
main()
或调用链中类似的高级对象),并将引用(或智能指针,取决于对象的生命周期有多复杂)传递给所有需要的对象。@Mike,@Als:well,如果应用程序需要真正的全局配置/存储对象,为什么不将其设置为全局(在命名空间内)?我能看到的唯一问题是线程,但这可以通过使用正确的线程习惯用法得到帮助,这些习惯用法可以在对象外部强制执行,也可以隐藏在全局/静态中。为什么要将其包装在类中,而不是在命名空间范围内声明它
extern
,实际上,
extern
是这种单一变量的最佳选择。因为@rubenvb已经提出了同样的建议;我给出了另一种方法(如果你仍然想保持它的静态,就说
)。除了保留
静态
关键字之外,你没有以任何方式“保持它的静态”,这在本文中有不同的含义。这完全等同于使其
extern
(即,它将链接从内部更改为外部),但由于引入了无意义的类而导致了额外的一层混乱。