看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《dreamboat66 (小嫩)》之銘言: : https://ideone.com/9ufeMX : 請問上述的程式碼 : 我不確定1和2 真正被push到stack上 : bar和foo誰先被push(我觀念上1和2都是 foo先 再來是bar) : 而我從印出this似乎1,2兩個push到stack的順序也是一樣(但不知道為啥最佳化後 stac k : address是小到大) : =============以上 不知道結論有沒有錯============ : 但以我的觀念, 我是覺得先被push就是最後被解構 : 但用stack的觀念上我無法解釋 為什麼解構順序會有差別? : 如果從code來看, 確實是很合理 但不知道為什麼stack就說不通? : 中間有什麼盲點我搞錯了? 或是因為一些手段 導致我光看this的位址是不準確的? : 謝謝 C++ 不論是什麼變數,建構 & 解構的順序相反 為什麼這樣規定? 假設有一個 Logger 物件和一個 Display 物件 當 Display 遇到錯誤的時候就會通知 Logger 所以 Display 存在的時候,Logger 也必須存在 因此 Display 和 Log 的建立順序應該是這樣: Logger logger; Display monitor; 這樣我們會合理的預期當 monitor 遇到錯誤的時候,一定可以通知 Logger 因為就算 Display 是在建構的過程中遇到錯誤,Logger 也早建構完成在那邊等了 可是,這裡有一個容易被忽略的問題,那就是解構順序 要是解構順序和建構順序相同的話,那意味著 Logger 將比 Display 更早被解構 要是真的這樣,那麼當 Display 在解構的過程中遭遇了錯誤,就會對 已經被解構的 Logger 操作,這就是所謂的 Dead Reference 造成的問題 竟然對一個已經解構的物件進行操作!!! 這樣的結果是未定義的 C++ 的設計當然不會讓這種事情發生,至少是不可能發生在 auto 變數身上 從上面這個例子可以看出因此『建構和解構順序相反』的原因 因為這樣才符合我們預期的「先宣告的變數生命周期較長」的假設 再來我們來看看 global 變數 global 變數也遵守著先建構後解構的規則 (事實上除了 new 出來的空間都遵守這個規則 ) 但是,這並不代表 global 變數和 auto 變數一樣可以利用這個機制解決這類的問題 問題就出在我們無法確定 global 變數的建構時間 我們知道 global 變數的初始化是在程式 loadding 的時候,因此不存在先後的問題 因此也無法保障解構順序 再來,剛剛的初始化機制只能用在可以成為 compile time constant 的型態身上 意思就是你的 class 必須要是像 C struct 那樣的 POD 才有可能適用這樣的初始化機制 其他無法成為 compile time constant 的型別,編譯器會自動 inline 一些程式碼幫助 這些 global 變數在程式開始的時候被初始化 這代表了你也無法單純透過宣告順序來決定 globals 的建構順序,當然更不可能得知解 構順序 再來是 static 變數 static 變數分兩種,種是 local static 變數,另一種是 global static 變數 global static 在這裡就不談了,它相當於 unnamed namespace 裡的 global 變數 我們關心的是 local static 變數 要是 local static 的型別能夠成為 compile time constant 則比照 global 辦理 要是不行的話,就會在第一次用到它的時候被初始化 因此某種程度上,這種 local static 變數的解構時間是能夠被預期的(只要程式流程能 夠被預期) 我們需要解決的課題是,該如何控制這些 global 和 static 的生命週期呢? 在 MCD 裡面有一章是 singleton pattern 的實作範例 裡面就對這類的問題提出了一些解決方案 在這裡就不贅述,有興趣的話可以去查查 phoneix singleton 和 std::atexit() 或是直接拿 MCD 來翻翻會是更好的選擇啦 XD -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 163.18.32.149 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1461989007.A.AC5.html ※ 編輯: CoNsTaR (101.14.146.203), 04/30/2016 13:00:44
dreamboat66: 可是以我的例子 bar and foo 都是auto var, 為啥 04/30 12:52
dreamboat66: 解構順序 會不一樣 難道在stack上 順序不一樣嗎?04/30 12:52
在你的例子,因為建構順序也不一樣啊
CoNsTaR: 改了一下文章內容 把我覺得比較模糊的地方拿掉了04/30 13:02
※ 編輯: CoNsTaR (101.14.146.203), 04/30/2016 13:06:56
dreamboat66: 但是以log看 建構感覺順序一樣 請問怎麼看出不一樣04/30 13:33
dreamboat66: 的?04/30 13:33
是我眼殘了 只看輸出就亂講話 你想要問的是 test() 的 foo 為何比 bar 更早解構吧? 好吧…我也不知道 XDD 不過你要不要試試看把 foo 建構式的 && 改成 const & 或其他的 搞不好結果會改變
james732: 推04/30 19:09
※ 編輯: CoNsTaR (101.13.3.184), 05/01/2016 12:32:47