通过 C++ 中的静态实例单例——进入源文件或头文件?

问题描述 投票:0回答:2

干杯,

我在“通过示例编程游戏 AI”中遇到了这段代码:

/* ------------------ MyClass.h -------------------- */
#ifndef MY_SINGLETON
#define MY_SINGLETON

class MyClass
{
private:

  // member data
  int m_iNum;

  //constructor is private
  MyClass(){}

  //copy ctor and assignment should be private
  MyClass(const MyClass &);
  MyClass& operator=(const MyClass &);

public:

  //strictly speaking, the destructor of a singleton should be private but some
  //compilers have problems with this so I've left them as public in all the
  //examples in this book
  ~MyClass();

  //methods
  int GetVal()const{return m_iNum;}
  static MyClass* Instance();
};

#endif

/* -------------------- MyClass.cpp ------------------- */

//this must reside in the cpp file; otherwise, an instance will be created
//for every file in which the header is included
MyClass* MyClass::Instance()
{
  static MyClass instance;

  return &instance;
}

我对作者的事实陈述感到困惑,即标头中函数内静态声明的变量将导致声明多个单独的静态变量

instance
。我认为我在我经常放入标头中的
getInstance()
函数的通常实现中没有看到这种行为(除了我喜欢使用指针并在第一次使用时初始化单例)。我在工作中使用 GCC。

那么标准是怎么说的呢?不合规的编译器会说什么?作者的说法正确吗?如果是,您能说出一些如果在标头中声明了

getInstance()
就会创建多个实例的编译器吗?

c++ singleton
2个回答
10
投票

在 C++ 中,没有什么可以阻止内联函数拥有静态变量,并且编译器必须安排使该变量在所有翻译单元之间通用(就像它必须为模板实例化静态类成员和静态函数变量所做的那样)。 7.1.2/4

static
函数中的
extern inline
变量始终引用同一个对象。

请注意,在 C 中,内联函数不能有静态变量(也不能引用具有内部链接的对象)。


1
投票

我已经尝试了OP用VS2008发布的代码的四种方式,并且

MyClass
内的
MyClass::Instance()
的静态实例似乎没有问题。

  1. Instance()
    定义于 MyClass.cpp:这是正常的方式 一切都很好。
  2. Instance()
    仅在内部定义 类声明。 这是 另一种选择,一切都很好。
  3. Instance()
    已定义
    inline
    在类之外,但在标题中 一切都很好。
  4. 如 3. 但没有
    inline
    和 链接器说有多个定义
    Instance()

我认为本书作者关心的是上面的4.并且知道MyClass的静态实例将在编译和链接的程序中得到处理。

© www.soinside.com 2019 - 2024. All rights reserved.