使用静态对象输出奇怪的输出

时间:2013-12-30 09:26:12

标签: c++ visual-c++

我无法理解发生了什么......

假设我有以下代码:

// main.cpp

#include "some_header.h"

void bar();

int main()
{
  foo();
  bar();
}

// file.cpp

#include "some_header.h"

void bar()
{
  foo();
}

// some_header.h

#include "foo.h"

inline
void foo()
{
  static Foo instance;
}

// foo.h

#include <iostream>

class Foo
{
public:
  Foo() { std::cout << "Foo::Foo() \n"; }
  ~Foo() { std::cout << "Foo::~Foo() \n"; }
};

输出

  

富::富()

     

富::〜美孚()

问题是:为什么输出中没有第二个“Foo :: Foo()”?我认为它应该在这里因为每个翻译单元(在我的情况下是main.cpp和file.cpp)应该有自己的Foo对象(因为静态关键字)。我错了吗?有人可以引用这个标准吗?

如果我从像这样的函数中移动Foo对象的定义

// some_header.h

#include "foo.h"

static Foo instance;

inline
void foo()
{

}

输出将是

  

富::富()

     

富::富()

     

富::〜美孚()

     

富::〜美孚()

它是内联魔法还是我错过了更基本的东西?

我需要做什么 - 我需要在我的仅头文件库的某个函数中添加boost :: mutex对象来同步一些WinAPI函数调用,如下所示:

inline
void some_func()
{
  static boost::mutex sync;
  boost::lock_guard<boost::mutex> lock(sync);
  // Call some WinAPI function
}

我该怎么做?

MSVC-11.0。

1 个答案:

答案 0 :(得分:5)

static是C ++中严重重载的关键字。在命名空间范围内,它意味着“实体具有内部链接,因此每个翻译单元都有自己的副本”。在函数范围,它意味着“函数只有一个这样的实体,它在函数调用中持续存在。”

因此,在您的情况下,函数foo()只有一个对象Foo instance具有局部范围,但具有全局生命周期。

至于你的互斥问题,我在看到你在问题中发布的内容时看不出有什么问题。 some_func()将具有互斥锁的单个实例,并且对some_fucn()的所有调用将共享该一个实例(并且从C ++ 11开始,它将被第一次这样的调用正确且线程安全地初始化)。我会说这正是你所需要的。