我有简单的单身
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
关键字吗?)
答案 0 :(得分:2)
它应该在提供的窗口下工作:
readlink
进行导出,__declspec(dllexport)
进行导入__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上,这不是必需的。