标头

时间:2016-02-25 15:36:36

标签: c++ class static

// 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在程序中定义了两次,这是预期的(因为类静态成员函数实际上是具有内部链接的常规函数​​,如果它们已定义到位,就像在这种情况下),这是你可以从反汇编中看到的。由于我们在机器代码中有两个带静态局部变量的函数。语言/标准如何限定他们的行为?

2 个答案:

答案 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变量。

相关问题