// SomeOtherClass.hpp
#pragma once
int someOtherCallMe();
class SomeOtherClass {
public:
static int callMe() {
static int _instance = 7;
++_instance;
return _instance;
}
};
// SomeOtherClass.cpp
#include "SomeOtherClass.hpp"
int
someOtherCallMe() {
return SomeOtherClass::callMe();
}
// main.cpp
#include "SomeOtherClass.hpp"
#include <iostream>
int
main() {
std::cout << SomeOtherClass::callMe();
std::cout << someOtherCallMe();
return 0;
}
我有三个文件:SomeOtherClass.hpp / cpp,main.cpp。这些文件导致两个二进制文件:共享库(SomeOtherClass.cpp)和可执行文件(main.cpp,与共享库链接)。
C ++是否保证在执行程序期间static <any-type> _instance
将是一个变量(与定义的二进制数无关)?
注意
澄清情况。我在这种情况下看到的困惑是,一方面,SomeOtherClass::callMe
在程序中定义了两次,这是预期的(因为类静态成员函数实际上是具有内部链接的常规函数,如果它们已定义到位,就像在这种情况下),这是你可以从反汇编中看到的。由于我们在机器代码中有两个带静态局部变量的函数。语言/标准如何限定他们的行为?
答案 0 :(得分:2)
是。静态将是单个值。许多其他事情没有明确定义或是标准的新内容。 (如果它们是全局的,它们什么时候被初始化?函数中的静态初始化代码是否是线程安全的?)但是,是的,你可以指望它只有一个。
如果要创建共享库(.so或.dll),这里唯一的澄清是超出标准但实际重要性:您不能静态(私下)将C ++类库链接到共享库。否则,如果您在两个不同的共享库中执行此操作,则会生成两个副本。 (此注释适用于有关库的所有内容,而不仅仅是静态变量。如果执行此操作,则会出现所有内容的重复。)
编辑:在许多平台(例如Linux和Windows)上,这可用于有目的地“隐藏”您的静态变量。如果你没有在dll / so之外访问你的函数/类(使用declspec或visibility属性),那么你可以确保你的dll / so有自己的整个类的副本。此技术可以帮助减少库之间不需要的交互。但是,在您的情况下,听起来您真的只想要一个,如果您的类在所有库中都具有适当的可见性(仅在一个库中可见,而其他库链接到该库),则会出现这种情况。
再次编辑以引用标准
如果在一个翻译单元中内联声明具有外部链接的功能,则应在其出现的所有翻译单元中内联声明;无需诊断。具有外部链接的内联函数在所有翻译单元中应具有相同的地址。 extern内联函数中的静态局部变量始终引用同一个对象。
7.1.2.4,C ++ 14
答案 1 :(得分:1)
C ++是否保证静态_instance在程序执行期间将是一个变量(与定义的二进制数无关)?
我认为这种语言无话可说。它没有讨论静态库或动态库。
实现的责任是提供机制以确保可以有一个定义。由用户决定是否使用实现提供的机制在函数中定义static
变量。