您好,登錄后才能下訂單哦!
1. //singleton.h #ifndef SINGLETON_H #define SINGLETON_H template <typename T> class singleton { public: static T* get_instance(); private: // static instance 的作用,主要是為了讓所有的 單例 都在main 執行前, //或者so加載成功時,調用其構造函數 class creator { public: creator() { get_instance(); } inline void dono()const{} }; static creator instance; }; //模板內嵌套類,需要用typename告知其是類型 template <typename T> typename singleton<T>::creator singleton<T>::instance; template <typename T> T* singleton<T>::get_instance() { static T t; instance.dono(); return &t; } #endif
#ifndef TESTC_H #define TESTC_H #include <iostream> using namespace std; class testc { public: ~testc(){cout<<"~test"<<endl;} testc() { hasinit=false; cout<<"testc is called"<<endl; } bool init(int mm) { if(hasinit) return true; m=mm; cout<<"init is called"<<endl; hasinit=true; } bool hasinit; int m; }; #endif
#include "singleton.h" #include "testc.h" int main() { testc * cc=singleton<testc>::get_instance(); cc->init(1); cout<<cc->m<<endl; testc *cc2=singleton<testc>::get_instance(); cc2->init(2); cout<<cc2->m<<endl; testc *c3=new testc; c3->init(3); cout<<c3->m<<endl; }
testc is called init is called 1 1 testc is called init is called 3 ~test 2.跨so 單例模板 會產生多實例問題 問題初步原因: 不同so中會對 類模板進行實例化,并在不同so中各存在 一個類副本。網上有人確認過,singleton<A> 產生的類A代碼,在不同so中 typeid(singleton<A>) 的返回值 type_info 不相等,但我自己確認結果是 兩者相等。 解決方法: 想辦法,讓單例類的實例化 singleton<A> 只在一個so中進行; class A { ... A* get_instance(){return singleton<A>::get_instance();} ... }; 想獲得單例時 執行 A::get_instance(),而非 singleton<A>::get_instance(); 在這里:testc 類會被 兩個不同的so liba.so,libb.so 使用其單例,如果按照1中的方法,則 在liba.so 和libb.so中都會 調用 singleton<testc>::get_instance(),但因為 liba.so ,libb.so 是不同的編譯單元, 編譯器會 為兩個 so產生 兩份類 testc 單例化的副本。(后續在好好梳理) 解決方法 #ifndef TESTC_H #define TESTC_H #include <iostream> using namespace std; class testc { public: ~testc(){cout<<"~test"<<endl;} testc() { hasinit=false; cout<<"testc is called"<<endl; } testc *get_instance(){return singleotn<testc>::get_instance()} bool init(int mm) { if(hasinit) return true; m=mm; cout<<"init is called"<<endl; hasinit=true; } bool hasinit; int m; }; #endif tectc::get_instance()
參考文獻,感謝兩位博主,
http://blog.cnbang.net/tech/2229/
http://blog.csdn.net/crayondeng/article/details/24853471
http://blog.csdn.net/fullsail/article/details/8483106
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。