C++ C++;头文件中定义的静态类方法中的静态变量 //SomeOtherClass.hpp #布拉格语一次 int someOtherCallMe(); 给别人上课{ 公众: 静态int callMe(){ 静态int_实例=7; ++_实例; 返回_实例; } }; //SomeOtherClass.cpp #包括“SomeOtherClass.hpp” int 有人叫我(){ 返回SomeOtherClass::callMe(); } //main.cpp #包括“SomeOtherClass.hpp” #包括 int main(){ std::cout

C++ C++;头文件中定义的静态类方法中的静态变量 //SomeOtherClass.hpp #布拉格语一次 int someOtherCallMe(); 给别人上课{ 公众: 静态int callMe(){ 静态int_实例=7; ++_实例; 返回_实例; } }; //SomeOtherClass.cpp #包括“SomeOtherClass.hpp” int 有人叫我(){ 返回SomeOtherClass::callMe(); } //main.cpp #包括“SomeOtherClass.hpp” #包括 int main(){ std::cout,c++,class,static,C++,Class,Static,是的。静态将是一个单一值。许多其他内容没有很好地定义或是新的标准。(如果它们是全局的,它们何时初始化?函数中静态初始化的代码是否线程安全?)但是,是的,您可以相信只有一个 这里唯一的澄清是在标准之外,但如果你正在创建一个共享库(.SO或.DLL),你就不能真正地把你的C++类库链接到共享库中。否则,如果你在两个不同的共享库中这样做,那么这将是两个副本。(此注释适用于库的所有内容,而不仅仅是静态变量。如果您这样做,则所有内容都会重复。) 编辑:在许多平台(如Linux和Windows)上,这可用于

是的。静态将是一个单一值。许多其他内容没有很好地定义或是新的标准。(如果它们是全局的,它们何时初始化?函数中静态初始化的代码是否线程安全?)但是,是的,您可以相信只有一个

这里唯一的澄清是在标准之外,但如果你正在创建一个共享库(.SO或.DLL),你就不能真正地把你的C++类库链接到共享库中。否则,如果你在两个不同的共享库中这样做,那么这将是两个副本。(此注释适用于库的所有内容,而不仅仅是静态变量。如果您这样做,则所有内容都会重复。)

编辑:在许多平台(如Linux和Windows)上,这可用于故意“隐藏”静态变量。如果您不使函数/类在dll/so之外可访问(使用declspec或可见性属性),然后您可以确保dll/so有其自己的整个类的副本。此技术可以帮助减少库之间不必要的交互。但是,在您的情况下,如果您的类在所有库中都具有适当的可见性,则听起来您只需要一个(仅在一个库中可见,其他库链接到该库)

再次编辑以参考标准

如果具有外部链接的函数在一个翻译单元中声明为内联,则应在其出现的所有翻译单元中声明为内联;无需诊断。具有外部链接的内联函数在所有翻译单元中应具有相同的地址。外部内联函数中的静态局部变量始终指向同一对象

7.1.2.4,C++14

C++是否保证静态的实例在程序执行期间将是一个变量(与定义的二进制文件无关)? 我不认为语言对此有什么可说的,它没有谈论静态库或动态库


实现的责任是提供一种机制来确保可以有一个定义。由用户来确保他们使用实现提供的机制来定义函数中的
静态
变量。

使用MS Visual Studio时,您需要使用当构建DLL并使用DLL使其工作时,请更正
\uuu declspec
。是的,我知道,谢谢。如果问题真的是关于跨越DLL边界的静态变量,那么应该在标题中提及,更重要的是在文本中提及。我同意您的看法,是用户选择它想要的内容并和我一起做但是在这种情况下,我会说因为静态函数(
SomeOtherClass::callMe
)在代码中被复制。静态变量也应该被复制,但至少在g++中是不应该被复制的。但另一方面,它不应该被复制,因为正如语言所说的
static
保证了单个对象。亲爱的Rob,谢谢你的努力,你的答案似乎最接近我现在想要的,我真的有我不知道你为什么会被否决,mb你在一开始写的smth奇怪,我实际上没有看变化历史,或者mb它只是草率的stackoverflow阅读器。如果你能提供一些参考标准和/或一些有价值的资源,我将不胜感激,这是什么样的链接,以及标准/语言限定了这种结构。我想我被否决了,因为这是一个很复杂的话题,很难用是/否来回答。我在被否决后还补充了说明。我认为标准中没有任何内容涉及DLL和共享二进制文件。信息来自项目负责人(我)谁必须管理一个有几十个DLL和许多开发人员的产品。我们已经犯了这些错误,并从中吸取了教训。底线是:如果它是共享的,在某个地方定义一次,正确地导出它,编译器会处理其余的。是的,我还看到它是一个只包含头的库,其中所有内容都是内联的,或者它是一个共享库在翻译单位中定义了所有的东西。我知道这更清楚(OHHH,C++ +…)).但我只是好奇,是否有什么东西定义了这种情况,即使不是dll/可执行文件的情况,而是在多个翻译单元中使用了类似于SomeOtherClass.hpp的头的情况,是否可以保证变量只有一个。请参阅更新。如果没有dll,则只有“常规”库和对象文件,那么是的。绝对保证只有一个。但是混淆仍然是一样的,为什么?因为实际上会有很多
SomeOtherClass::callMe
函数作为转换单元。然后它如何解析静态变量,它如何限定它。因为在常规命名空间声明静态变量的情况下不可能有和翻译单位一样多的变量。那么什么是静态局部变量呢?
// 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;
}