2016-01-25 18 views
1

我有簡單單用是否有可能具有應用程序級別的單身人士?

class Options { 
    private: 
     Options() 
     {}; 
     Options(Options const&); 
     void operator=(Options const&); 
    public: 
     static Options& get() 
     { 
     static Options INSTANCE; 
     return INSTANCE; 
     } 
    }; 

我有這個定義在頭共享庫中的

但是當我調用get()首先從應用BI看怎麼有實例被創建和然後我調用共享庫C的方法,並使用get()那裏我得到了另一個實例...

我該怎麼樣才能應用程序級別單例? (是否與extern關鍵字有關?)

+0

所以跨多個應用程序實例的單一單? – Downvoter

+0

@cad沒有應用程序實例,但一個應用程序和共享庫...(模塊) – Cynede

回答

2

應該提供窗口下工作:

  • 你一直使用__declspec(dllexport)出口和__declspec(dllimport)進口
  • Options::get()的實施是在CPP文件移動,使其只在DLL中存在。

下面是一個例子:

options.dll建立與定義OPTIONS_EXPORT符號:

options.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與一起構建定義並與options.lib聯符號:

c.h:

#pragma once 

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

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

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

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; 
} 

輸出:Ok

+0

謝謝!應該在哪裏定義OPTIONS_EXPORT? – Cynede

+0

@ Heather:符號應該在構建dll的項目的屬性中定義。 –

+0

順便說一句,請更正#idfefs通過添加dllimport,有錯別字我猜 – Cynede

1

問題是您的所有應用程序和庫都將自己的類的副本編譯到庫中,因爲您告訴他們所有人應如何看待該類。

首先,將get函數的實現移動到源文件中。完成這一步並編譯完成後,您應該看到共享庫不知道該函數應該如何顯示,並且它們不會編譯(鏈接器錯誤,除了包含該類的庫之外)。

從那裏開始通過讓應用程序和其他庫知道從哪裏鏈接函數來修復編譯。

在Windows上,您需要導出庫中的類,它使用__declspec(dllexport)實現。 在庫和可能的應用程序中,您需要使用__declspec(dllimport)來導入類。 在Linux上,這不應該是必需的。

+0

沒有幫助,我已經移動到cpp一個__declspec(dllexport)來獲取定義,但我仍然看到構造函數Options() {};被稱爲B和C – Cynede

+0

@ Heather所以我假設你正在使用Windows? –

+0

是的,我正在使用windows – Cynede

相關問題