是否有可能有应用程序级单身人士?

时间:2016-01-25 07:44:33

标签: c++ singleton

我有简单的单身

  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关键字吗?)

2 个答案:

答案 0 :(得分:2)

它应该在提供的窗口下工作:

  • 您始终使用readlink进行导出,__declspec(dllexport)进行导入
  • {c}文件中的__declspec(dllimport)的实现被移动,以便它只存在于DLL中。

以下是一个例子:

options.dll构建时定义了Options::get()符号:

options.h:

OPTIONS_EXPORT

options.cpp:

#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.dll构建的虚拟c.dll,其#include "Options.h" Options& Options::get() { static Options INSTANCE; return INSTANCE; } 符号已定义并与C_EXPORT链接:

c.h:

options.lib

c.cpp:

#pragma once

#ifdef C_EXPORTS
#define dll __declspec(dllexport)
#else
#define dll __declspec(dllimport)
#endif

#include "../a/options.h"

namespace C {
    dll Options& relay();
};

与options.dll和c.dll相关联的最小主要内容:

#include "c.h"

Options& C::relay() {
    Options& opt = Options::get();
    return opt;
}

输出符合预期:#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; }

答案 1 :(得分:1)

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

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

从那里开始修复编译,让应用程序和其他库知道从哪里链接函数。

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