[問題] 建構template繼承類別內的static變數

看板C_and_CPP作者 (仙人掌)時間9年前 (2015/01/30 16:12), 9年前編輯推噓2(2022)
留言24則, 5人參與, 最新討論串1/1
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) g++ 4.7.1 with C++11 問題(Question): 程式的目的是想要在建構許多類別"之前"就會做一些固定的事情,假設為印出 show, 因此使用 static member data 達到這個目的: template<class T> struct ShowClass { ShowClass() { std::cout << "show" << std::endl; } }; struct Test { private: static ShowClass<Test> our_show; }; ShowClass<Test> Test::our_show; 因為這種的類別會有很多個,每個都要加 static member data 與初始化很麻煩, 於是想額外定義新的類別,並且繼承自它: template <typename T> struct AutoShow { AutoShow() { &our_show; } protected: static ShowClass<T> our_show; }; template <typename T> ShowClass<T> AutoShow<T>::our_show; 所以原本的 Test 就會變成 struct TestOK : public AutoShow<TestOK> { public: TestOK() {} }; 成功在 main 開始做事情之前就會印出 show, 但是,如果把 constructor 拿掉讓它是預設值產生的話,就沒辦法印出, struct TestFail : public AutoShow<TestFail> { }; TestFail 沒辦法印出 show。 請問這是什麼原因導致會有這種現象? 必須手動替每個類別加上 constructor 才行嗎? 程式碼(Code):(請善用置底文網頁, 記得排版) http://ideone.com/VSRNbz 為了清楚辨認出印出 show 的類別, 範例使用 template_to_string 與巨集 DEFINE_TYPE, 將 template type 轉成 string 並印出。 執行結果: Test show TestOK show 預期結果: Test show TestOK show TestFail show 補充說明 在 main 建構出 TestFail 的話是會印出 show, 但是我想要的效果是不必建構出 TestFail 實體就能印出 show。 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 140.122.184.141 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1422605547.A.D74.html ※ 編輯: ukjhsa (140.122.184.141), 01/30/2015 16:16:03

01/30 17:57, , 1F
你的例子clang跑會segfault
01/30 17:57, 1F

01/30 17:58, , 2F
猜應該是因為你的TestFail根本沒用到 所以連default ctor
01/30 17:58, 2F

01/30 17:58, , 3F
都沒有幫你產生
01/30 17:58, 3F

01/30 18:00, , 4F
如果你在main中宣告一個TestFail 就會出現TestFail show了
01/30 18:00, 4F

01/30 20:55, , 5F
怪了在OSX下clang沒問題 但在ubuntu下clang就segfault
01/30 20:55, 5F

01/30 20:56, , 6F
似乎是 TestOK 出問題,但是找不到問題在哪裡..
01/30 20:56, 6F

01/30 20:58, , 7F
請問是否有其他方法可以不必在main宣告就能show的方法?
01/30 20:58, 7F

01/30 23:37, , 8F
segfault的原因我猜是你的static variable比cout早建構
01/30 23:37, 8F

01/30 23:37, , 9F
用到還沒好的cout 就炸了
01/30 23:37, 9F

01/30 23:42, , 10F
雖然不知道你想用ctor做什麼事情 總之不建議這樣用
01/30 23:42, 10F

01/30 23:42, , 11F
01/30 23:42, 11F

01/31 00:29, , 12F
感謝樓上,沒有 cout 的話確實就不會 segfault 了
01/31 00:29, 12F

01/31 00:33, , 13F
原本打算是想用個map存類別名字與其實體指標("A",A*)
01/31 00:33, 13F

01/31 00:34, , 14F
然後就可以用不同的類別名字 拿到實體
01/31 00:34, 14F

01/31 00:35, , 15F
所以每個類別都要註冊其名字到map裡面
01/31 00:35, 15F

01/31 00:37, , 16F
要在main事先寫非常多行這種註冊的程式碼
01/31 00:37, 16F

01/31 00:39, , 17F
雖然可以在使用A的時候讓他ctor去註冊,但這也要在main
01/31 00:39, 17F

01/31 00:41, , 18F
宣告所有會用到的類別 讓他們產生的時候再註冊
01/31 00:41, 18F

01/31 00:42, , 19F
想讓main乾淨點於是想利用static變數 不過忽略了建構順序
01/31 00:42, 19F

01/31 00:45, , 20F
不只cout還沒建構好, 連map也可能還沒建構好
01/31 00:45, 20F

01/31 00:45, , 21F
之前有幹過類似的事 "init_priority"
01/31 00:45, 21F

01/31 00:48, , 22F
因為會動態的從文字檔讀入名字A,B,...所以要先通通註冊好
01/31 00:48, 22F

01/31 00:51, , 23F
那我覺得用 static local 好些
01/31 00:51, 23F

01/31 02:18, , 24F
工廠方法?
01/31 02:18, 24F
文章代碼(AID): #1Kopphrq (C_and_CPP)