// 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;
}
Run Code Online (Sandbox Code Playgroud)
我有三个文件:SomeOtherClass.hpp/cpp,main.cpp.这些文件产生两个二进制文件:共享库(SomeOtherClass.cpp)和可执行文件(main.cpp,与共享库链接).
C++保证static <any-type> _instance在程序执行期间将是一个变量(与定义的二进制数无关)?
注意
澄清情况.我在这种情况下看到的混乱是,一方面,SomeOtherClass::callMe它在程序中定义了两次,这是预期的(因为类静态成员函数实际上是具有内部链接的常规函数,如果它们被定义到位,就像在这种情况下一样) ),这是你可以从反汇编中看到的.由于我们在机器代码中有两个带静态局部变量的函数.语言/标准如何限定他们的行为?
是的。静态将是单个值。许多其他内容没有明确定义或者对于标准来说是新的。(如果它们是全局的,那么它们什么时候初始化?函数内静态初始化的代码是线程安全的吗?)但是,是的,您可以相信只有一个。
这里唯一的说明超出了标准,但如果您要创建共享库(.so 或 .dll),则具有实际重要性:您不能静态(私有)地将 C++ 类库链接到共享库。否则,如果您在两个不同的共享库中执行此操作,则会生成两个副本。(此注释适用于有关库的所有内容,而不仅仅是静态变量。如果这样做,那么所有内容都会重复。)
编辑:在许多平台(例如 Linux 和 Windows)上,这可用于有目的地“隐藏”静态变量。如果您不让您的函数/类在 dll/so 之外可访问(使用 declspec 或可见性属性),那么您可以确保您的 dll/so 拥有整个类的自己的副本。此技术可以帮助减少库之间不必要的交互。然而,就您的情况而言,听起来您确实只需要一个,如果您的类在所有库中具有适当的可见性(仅在一个库中可见,而其他库链接到该库),就会出现这种情况。
再次编辑参考标准
如果具有外部链接的函数在一个翻译单元中被声明为内联,则该函数在其出现的所有翻译单元中也应被声明为内联;无需诊断。具有外部链接的内联函数在所有翻译单元中应具有相同的地址。外部内联函数中的静态局部变量始终引用同一个对象。
7.1.2.4、C++14
| 归档时间: |
|
| 查看次数: |
902 次 |
| 最近记录: |