C++ 是否可以有应用程序级单例?

C++ 是否可以有应用程序级单例?,c++,singleton,C++,Singleton,我有一个简单的单身汉 class Options { private: Options() {}; Options(Options const&); void operator=(Options const&); public: static Options& get() { static Options INSTANCE; return INSTA

我有一个简单的单身汉

  class Options {
    private:
      Options()
      {};
      Options(Options const&);
      void operator=(Options const&);
    public:
      static Options& get()
      {
        static Options INSTANCE;
        return INSTANCE;
      }
    };
我在共享库A的标题中得到了这个定义

但当我首先从应用程序B调用get()时,我看到了实例是如何创建的,然后我从共享库C调用了方法,并在那里使用get()得到了另一个实例


我怎么能有类似的应用程序级单例呢?(这是否与
extern
关键字有关?

问题是,您的所有应用程序和库都将自己的类副本编译到库中,因为您告诉了它们类的外观

首先,首先将
get
函数的实现移动到源文件中。完成此操作并编译后,您应该看到共享库不知道函数的外观,并且它们不会编译(链接器错误,包含该类的库除外)

从这里开始,通过让应用程序和其他库知道从何处链接函数来修复编译

在windows上,您需要使用
\uu declspec(dllexport)
导出库中实现的类。 在库和可能的应用程序上,您需要使用
\uu declspec(dllimport)
导入类。
在Linux上,这是不必要的。

它应该在windows下工作,提供:

  • 导出时始终使用
    \u declspec(dllexport)
    ,导入时始终使用
    \u declspec(dllimport)
  • Options::get()
    的实现在cpp文件中移动,以便它只存在于DLL中
以下是一个例子:

定义了
options\u EXPORT
符号的options.dll生成:

选项h:

#pragma once

#ifdef OPTIONS_EXPORTS
#define DLLAPI __declspec(dllexport)
#else
#define DLLAPI __declspec(dllimport)
#endif

class DLLAPI Options
{
    private:
      Options()
      {};
      Options(Options const&);
      void operator=(Options const&);
    public:
      static Options& get();
      int val;
};
options.cpp:

#include "Options.h"

Options& Options::get()
{
    static Options INSTANCE;
    return INSTANCE;
}
使用options.dll构建的伪c.dll,其中定义了
c\u导出
符号,并与
options.lib
链接:

c、 h:

c、 cpp:

#include "c.h"

Options& C::relay() {
    Options& opt = Options::get();
    return opt;
}
以及与options.dll和c.dll链接的最小主链接:

#include <iostream>
#include "../a/options.h"
#include "../c/c.h"

int main() {
    Options& o1 = Options::get();
    o1.val = 12;
    Options& o2 = C::relay();

    std::cout << ((o1.val == o2.val) ? "Ok" : "Ko") << std::endl;
    return 0;
}
#包括
#包括“./a/options.h”
#包括“./c/c.h”
int main(){
Options&o1=Options::get();
o1.val=12;
选项&o2=C::relay();

std::是否可以跨多个应用程序实例使用单个实例?@cad不是应用程序实例,而是一个应用程序和共享库…(模块)没有帮助,我已转到cpp和_udeclspec(dllexport)以获取calss中的定义,但我仍然看到构造函数选项()如何{};在B和B中调用C@Heather因此,我假设您使用的是Windows?@Heather:符号应该在构建dll的项目属性中定义。顺便说一句,请通过添加dllimport来更正#IDFEF,我猜是打字错误
#include <iostream>
#include "../a/options.h"
#include "../c/c.h"

int main() {
    Options& o1 = Options::get();
    o1.val = 12;
    Options& o2 = C::relay();

    std::cout << ((o1.val == o2.val) ? "Ok" : "Ko") << std::endl;
    return 0;
}